summaryrefslogtreecommitdiff
path: root/support/highlight/src
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/highlight/src
Initial commit
Diffstat (limited to 'support/highlight/src')
-rw-r--r--support/highlight/src/cli/arg_parser.cc193
-rw-r--r--support/highlight/src/cli/arg_parser.h95
-rw-r--r--support/highlight/src/cli/cmdlineoptions.cpp1031
-rw-r--r--support/highlight/src/cli/cmdlineoptions.h471
-rw-r--r--support/highlight/src/cli/help.cpp185
-rw-r--r--support/highlight/src/cli/help.h42
-rw-r--r--support/highlight/src/cli/main.cpp709
-rw-r--r--support/highlight/src/cli/main.h117
-rw-r--r--support/highlight/src/core/ansigenerator.cpp109
-rw-r--r--support/highlight/src/core/ansigenerator.h89
-rw-r--r--support/highlight/src/core/astyle/ASBeautifier.cpp2658
-rw-r--r--support/highlight/src/core/astyle/ASEnhancer.cpp582
-rw-r--r--support/highlight/src/core/astyle/ASFormatter.cpp4520
-rw-r--r--support/highlight/src/core/astyle/ASResource.cpp547
-rw-r--r--support/highlight/src/core/astyle/ASStreamIterator.cpp167
-rw-r--r--support/highlight/src/core/astyle/ASStreamIterator.h101
-rw-r--r--support/highlight/src/core/astyle/astyle.h802
-rw-r--r--support/highlight/src/core/astyle/astyle_main.cpp2535
-rw-r--r--support/highlight/src/core/astyle/astyle_main.h268
-rw-r--r--support/highlight/src/core/bbcodegenerator.cpp128
-rw-r--r--support/highlight/src/core/bbcodegenerator.h90
-rw-r--r--support/highlight/src/core/charcodes.h99
-rw-r--r--support/highlight/src/core/codegenerator.cpp1804
-rw-r--r--support/highlight/src/core/codegenerator.h729
-rw-r--r--support/highlight/src/core/configurationreader.cpp112
-rw-r--r--support/highlight/src/core/configurationreader.h80
-rw-r--r--support/highlight/src/core/ctagsreader.cpp99
-rw-r--r--support/highlight/src/core/ctagsreader.h104
-rw-r--r--support/highlight/src/core/datadir.cpp181
-rw-r--r--support/highlight/src/core/datadir.h108
-rw-r--r--support/highlight/src/core/documentstyle.cpp168
-rw-r--r--support/highlight/src/core/documentstyle.h138
-rw-r--r--support/highlight/src/core/elementstyle.cpp111
-rw-r--r--support/highlight/src/core/elementstyle.h121
-rw-r--r--support/highlight/src/core/enums.h109
-rw-r--r--support/highlight/src/core/htmlgenerator.cpp477
-rw-r--r--support/highlight/src/core/htmlgenerator.h195
-rw-r--r--support/highlight/src/core/languagedefinition.cpp396
-rw-r--r--support/highlight/src/core/languagedefinition.h325
-rw-r--r--support/highlight/src/core/latexgenerator.cpp335
-rw-r--r--support/highlight/src/core/latexgenerator.h118
-rw-r--r--support/highlight/src/core/platform_fs.cpp339
-rw-r--r--support/highlight/src/core/platform_fs.h68
-rw-r--r--support/highlight/src/core/preformatter.cpp206
-rw-r--r--support/highlight/src/core/preformatter.h150
-rw-r--r--support/highlight/src/core/re/Matcher.cpp178
-rw-r--r--support/highlight/src/core/re/Matcher.h255
-rw-r--r--support/highlight/src/core/re/Pattern.cpp1655
-rw-r--r--support/highlight/src/core/re/Pattern.h1658
-rw-r--r--support/highlight/src/core/rtfgenerator.cpp363
-rw-r--r--support/highlight/src/core/rtfgenerator.h146
-rw-r--r--support/highlight/src/core/stringtools.cpp111
-rw-r--r--support/highlight/src/core/stringtools.h90
-rw-r--r--support/highlight/src/core/stylecolour.cpp157
-rw-r--r--support/highlight/src/core/stylecolour.h106
-rw-r--r--support/highlight/src/core/svggenerator.cpp248
-rw-r--r--support/highlight/src/core/svggenerator.h95
-rw-r--r--support/highlight/src/core/texgenerator.cpp303
-rw-r--r--support/highlight/src/core/texgenerator.h93
-rw-r--r--support/highlight/src/core/version.h36
-rw-r--r--support/highlight/src/core/xhtmlgenerator.cpp92
-rw-r--r--support/highlight/src/core/xhtmlgenerator.h68
-rw-r--r--support/highlight/src/core/xmlgenerator.cpp202
-rw-r--r--support/highlight/src/core/xmlgenerator.h86
-rw-r--r--support/highlight/src/core/xterm256generator.cpp208
-rw-r--r--support/highlight/src/core/xterm256generator.h111
-rw-r--r--support/highlight/src/gui-qt/Makefile277
-rw-r--r--support/highlight/src/gui-qt/highlight-gui.qrc6
-rw-r--r--support/highlight/src/gui-qt/highlight.pro39
-rw-r--r--support/highlight/src/gui-qt/highlight.xpm1173
-rw-r--r--support/highlight/src/gui-qt/highlight_de_DE.ts1159
-rw-r--r--support/highlight/src/gui-qt/highlight_es_ES.ts1156
-rw-r--r--support/highlight/src/gui-qt/hl_icon2.pngbin0 -> 105947 bytes
-rw-r--r--support/highlight/src/gui-qt/hl_icon_exe.icobin0 -> 9662 bytes
-rw-r--r--support/highlight/src/gui-qt/io_report.cpp68
-rw-r--r--support/highlight/src/gui-qt/io_report.h56
-rw-r--r--support/highlight/src/gui-qt/io_report.ui121
-rw-r--r--support/highlight/src/gui-qt/main.cpp54
-rw-r--r--support/highlight/src/gui-qt/mainwindow.cpp1080
-rw-r--r--support/highlight/src/gui-qt/mainwindow.h123
-rw-r--r--support/highlight/src/gui-qt/mainwindow.ui2147
-rw-r--r--support/highlight/src/gui-qt/moc_io_report.cpp69
-rw-r--r--support/highlight/src/gui-qt/moc_mainwindow.cpp134
-rw-r--r--support/highlight/src/gui-qt/moc_showtextfile.cpp79
-rw-r--r--support/highlight/src/gui-qt/precomp.h26
-rw-r--r--support/highlight/src/gui-qt/showtextfile.cpp72
-rw-r--r--support/highlight/src/gui-qt/showtextfile.h54
-rw-r--r--support/highlight/src/gui-qt/showtextfile.ui84
-rw-r--r--support/highlight/src/gui-qt/ui_io_report.h134
-rw-r--r--support/highlight/src/gui-qt/ui_mainwindow.h1860
-rw-r--r--support/highlight/src/gui-qt/ui_showtextfile.h105
-rw-r--r--support/highlight/src/makefile218
92 files changed, 38566 insertions, 0 deletions
diff --git a/support/highlight/src/cli/arg_parser.cc b/support/highlight/src/cli/arg_parser.cc
new file mode 100644
index 0000000000..55e440d94f
--- /dev/null
+++ b/support/highlight/src/cli/arg_parser.cc
@@ -0,0 +1,193 @@
+/* Arg_parser - A POSIX/GNU command line argument parser.
+ Copyright (C) 2006, 2007, 2008 Antonio Diaz Diaz.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <cstring>
+#include <string>
+#include <vector>
+
+#include "arg_parser.h"
+
+
+bool Arg_parser::parse_long_option( const char * const opt, const char * const arg,
+ const Option options[], int & argind ) throw()
+ {
+ unsigned int len;
+ int index = -1;
+ bool exact = false, ambig = false;
+
+ for( len = 0; opt[len+2] && opt[len+2] != '='; ++len ) ;
+
+ // Test all long options for either exact match or abbreviated matches.
+ for( int i = 0; options[i].code != 0; ++i )
+ if( options[i].name && !std::strncmp( options[i].name, &opt[2], len ) )
+ {
+ if( std::strlen( options[i].name ) == len ) // Exact match found
+ { index = i; exact = true; break; }
+ else if( index < 0 ) index = i; // First nonexact match found
+ else if( options[index].code != options[i].code ||
+ options[index].has_arg != options[i].has_arg )
+ ambig = true; // Second or later nonexact match found
+ }
+
+ if( ambig && !exact )
+ {
+ _error = "option `"; _error += opt; _error += "' is ambiguous";
+ return false;
+ }
+
+ if( index < 0 ) // nothing found
+ {
+ _error = "unrecognized option `"; _error += opt; _error += '\'';
+ return false;
+ }
+
+ ++argind;
+ data.push_back( Record( options[index].code ) );
+
+ if( opt[len+2] ) // `--<long_option>=<argument>' syntax
+ {
+ if( options[index].has_arg == no )
+ {
+ _error = "option `--"; _error += options[index].name;
+ _error += "' doesn't allow an argument";
+ return false;
+ }
+ if( options[index].has_arg == yes && !opt[len+3] )
+ {
+ _error = "option `--"; _error += options[index].name;
+ _error += "' requires an argument";
+ return false;
+ }
+ data.back().argument = &opt[len+3];
+ return true;
+ }
+
+ if( options[index].has_arg == yes )
+ {
+ if( !arg )
+ {
+ _error = "option `--"; _error += options[index].name;
+ _error += "' requires an argument";
+ return false;
+ }
+ ++argind; data.back().argument = arg;
+ return true;
+ }
+
+ return true;
+ }
+
+
+bool Arg_parser::parse_short_option( const char * const opt, const char * const arg,
+ const Option options[], int & argind ) throw()
+ {
+ int cind = 1; // character index in opt
+
+ while( cind > 0 )
+ {
+ int index = -1;
+ const unsigned char code = opt[cind];
+
+ if( code != 0 )
+ for( int i = 0; options[i].code; ++i )
+ if( code == options[i].code )
+ { index = i; break; }
+
+ if( index < 0 )
+ {
+ _error = "invalid option -- "; _error += code;
+ return false;
+ }
+
+ data.push_back( Record( code ) );
+ if( opt[++cind] == 0 ) { ++argind; cind = 0; } // opt finished
+
+ if( options[index].has_arg != no && cind > 0 && opt[cind] )
+ {
+ data.back().argument = &opt[cind]; ++argind; cind = 0;
+ }
+ else if( options[index].has_arg == yes )
+ {
+ if( !arg || !arg[0] )
+ {
+ _error = "option requires an argument -- "; _error += code;
+ return false;
+ }
+ data.back().argument = arg; ++argind; cind = 0;
+ }
+ }
+ return true;
+ }
+
+
+Arg_parser::Arg_parser( const int argc, const char * const argv[],
+ const Option options[], const bool in_order ) throw()
+ {
+ if( argc < 2 || !argv || !options ) return;
+
+ std::vector< std::string > non_options; // skipped non-options
+ int argind = 1; // index in argv
+
+ while( argind < argc )
+ {
+ const unsigned char ch1 = argv[argind][0];
+ const unsigned char ch2 = ( ch1 ? argv[argind][1] : 0 );
+
+ if( ch1 == '-' && ch2 ) // we found an option
+ {
+ const char * const opt = argv[argind];
+ const char * const arg = (argind + 1 < argc) ? argv[argind+1] : 0;
+ if( ch2 == '-' )
+ {
+ if( !argv[argind][2] ) { ++argind; break; } // we found "--"
+ else if( !parse_long_option( opt, arg, options, argind ) ) break;
+ }
+ else if( !parse_short_option( opt, arg, options, argind ) ) break;
+ }
+ else
+ {
+ if( !in_order ) non_options.push_back( argv[argind++] );
+ else { data.push_back( Record() ); data.back().argument = argv[argind++]; }
+ }
+ }
+ if( _error.size() ) data.clear();
+ else
+ {
+ for( unsigned int i = 0; i < non_options.size(); ++i )
+ { data.push_back( Record() ); data.back().argument.swap( non_options[i] ); }
+ while( argind < argc )
+ { data.push_back( Record() ); data.back().argument = argv[argind++]; }
+ }
+ }
+
+
+Arg_parser::Arg_parser( const char * const opt, const char * const arg,
+ const Option options[] ) throw()
+ {
+ if( !opt || !opt[0] || !options ) return;
+
+ if( opt[0] == '-' && opt[1] ) // we found an option
+ {
+ int argind = 1; // dummy
+ if( opt[1] == '-' )
+ { if( opt[2] ) parse_long_option( opt, arg, options, argind ); }
+ else
+ parse_short_option( opt, arg, options, argind );
+ if( _error.size() ) data.clear();
+ }
+ else { data.push_back( Record() ); data.back().argument = opt; }
+ }
diff --git a/support/highlight/src/cli/arg_parser.h b/support/highlight/src/cli/arg_parser.h
new file mode 100644
index 0000000000..b0e44a8770
--- /dev/null
+++ b/support/highlight/src/cli/arg_parser.h
@@ -0,0 +1,95 @@
+/* Arg_parser - A POSIX/GNU command line argument parser.
+ Copyright (C) 2006, 2007, 2008 Antonio Diaz Diaz.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Arg_parser reads the arguments in `argv' and creates a number of
+ option codes, option arguments and non-option arguments.
+
+ In case of error, `error' returns a non-empty error message.
+
+ `options' is an array of `struct Option' terminated by an element
+ containing a code which is zero. A null name means a short-only
+ option. A code value outside the unsigned char range means a
+ long-only option.
+
+ Arg_parser normally makes it appear as if all the option arguments
+ were specified before all the non-option arguments for the purposes
+ of parsing, even if the user of your program intermixed option and
+ non-option arguments. If you want the arguments in the exact order
+ the user typed them, call `Arg_parser' with `in_order' = true.
+
+ The argument `--' terminates all options; any following arguments are
+ treated as non-option arguments, even if they begin with a hyphen.
+
+ The syntax for optional option arguments is `-<short_option><argument>'
+ (without whitespace), or `--<long_option>=<argument>'.
+*/
+
+class Arg_parser
+{
+ public:
+ enum Has_arg { no, yes, maybe };
+
+ struct Option
+ {
+ int code; // Short option letter or code ( code != 0 )
+ const char * name; // Long option name (maybe null)
+ Has_arg has_arg;
+ };
+
+ private:
+ struct Record
+ {
+ int code;
+ std::string argument;
+ Record ( const int c = 0 ) : code ( c ) {}
+ };
+
+ std::string _error;
+ std::vector< Record > data;
+
+ bool parse_long_option ( const char * const opt, const char * const arg,
+ const Option options[], int & argind ) throw();
+ bool parse_short_option ( const char * const opt, const char * const arg,
+ const Option options[], int & argind ) throw();
+
+ public:
+ Arg_parser ( const int argc, const char * const argv[],
+ const Option options[], const bool in_order = false ) throw();
+
+ // Restricted constructor. Parses a single token and argument (if any)
+ Arg_parser ( const char * const opt, const char * const arg,
+ const Option options[] ) throw();
+
+ const std::string & error() const throw() { return _error; }
+
+ // The number of arguments parsed (may be different from argc)
+ int arguments() const throw() { return data.size(); }
+
+ // If code( i ) is 0, argument( i ) is a non-option.
+ // Else argument( i ) is the option's argument (or empty).
+ int code ( const int i ) const throw()
+ {
+ if ( i >= 0 && i < arguments() ) return data[i].code;
+ else return 0;
+ }
+
+ const std::string & argument ( const int i ) const throw()
+ {
+ if ( i >= 0 && i < arguments() ) return data[i].argument;
+ else return _error;
+ }
+};
diff --git a/support/highlight/src/cli/cmdlineoptions.cpp b/support/highlight/src/cli/cmdlineoptions.cpp
new file mode 100644
index 0000000000..21c7646bda
--- /dev/null
+++ b/support/highlight/src/cli/cmdlineoptions.cpp
@@ -0,0 +1,1031 @@
+/***************************************************************************
+ cmdlineoptions.cpp - description
+ -------------------
+ begin : Sun Nov 25 2001
+ copyright : (C) 2001-2008 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "cmdlineoptions.h"
+#include "platform_fs.h"
+#include "configurationreader.h"
+#include "datadir.h"
+#include <sstream>
+#include <cstdio>
+
+#include "arg_parser.h"
+
+using namespace std;
+
+
+CmdLineOptions::CmdLineOptions ( const int argc, const char *argv[] ) :
+ numberSpaces ( 0 ),
+ lineNrWidth ( 5 ),
+ lineLength ( 80 ),
+ lineNrStart ( 1 ),
+ wrappingStyle ( highlight::WRAP_DISABLED ),
+ outputType ( highlight::HTML ),
+ keywordCase ( StringTools::CASE_UNCHANGED ),
+ className ( "hl" ),
+ opt_syntax ( false ),
+ opt_include_style ( false ),
+ opt_help ( false ),
+ opt_version ( false ),
+ opt_verbose ( false ),
+ opt_print_config ( false ),
+ opt_linenumbers ( false ),
+ opt_style ( false ),
+ opt_batch_mode ( false ),
+ opt_fragment ( false ) ,
+ opt_attach_line_anchors ( false ),
+ opt_show_themes ( false ),
+ opt_show_langdefs ( false ),
+ opt_printindex ( false ),
+ opt_quiet ( false ),
+ opt_replacequotes ( false ),
+ opt_babel ( false ),
+ opt_print_progress ( false ),
+ opt_fill_zeroes ( false ),
+ opt_stylepath_explicit ( false ),
+ opt_force_output ( false ),
+ opt_ordered_list ( false ),
+ opt_fnames_as_anchors ( false ),
+ opt_validate ( false ),
+ opt_inline_css ( false ),
+ opt_enclose_pre ( false ),
+ opt_char_styles ( false ),
+ opt_pretty_symbols ( false ),
+ opt_delim_CR (false),
+ opt_print_style(false),
+ opt_no_trailing_nl(false),
+ configFileRead ( false ),
+ anchorPrefix ( "l" ),
+ helpLang ( "en" ),
+ encodingName ( "ISO-8859-1" )
+{
+
+ loadConfigurationFile();
+
+ enum Optcode
+ {
+ S_OPT_ADDCONFDIR = 256, S_OPT_ENCLOSE_PRE, S_OPT_FORCE_OUTPUT,
+ S_OPT_INLINE_CSS, S_OPT_KW_CASE,
+ S_OPT_MARK_LINES, S_OPT_PRINT_CONFIG, S_OPT_TEST_INPUT,
+ S_OPT_SVG_WIDTH, S_OPT_SVG_HEIGHT, S_OPT_CLASSNAME, S_OPT_RTF_CHAR_STYLES,
+ S_OPT_SKIP_UNKNOWN,
+ S_OPT_COMPAT_DOC, S_OPT_COMPAT_NODOC, S_OPT_COMPAT_TAB, S_OPT_COMPAT_CSS,
+ S_OPT_COMPAT_OUTDIR, S_OPT_COMPAT_FAILSAFE, S_OPT_COMPAT_OUTFORMAT,
+ S_OPT_COMPAT_SRCLANG, S_OPT_COMPAT_LINENUM, S_OPT_COMPAT_LINEREF,
+ S_OPT_CTAGS_FILE, S_OPT_PRETTY_SYMBOLS, S_OPT_EOL_DELIM_CR, S_OPT_START_NESTED,
+ S_OPT_PRINT_STYLE, S_OPT_NO_TRAILING_NL
+ };
+
+ const Arg_parser::Option options[] =
+ {
+ { 'a', OPT_ANCHORS, Arg_parser::no },
+ { 'A', OPT_ANSI, Arg_parser::no },
+ { 'b', OPT_BABEL, Arg_parser::no },
+ { 'B', OPT_BATCHREC, Arg_parser::yes },
+ { 'c', OPT_STYLE_OUT, Arg_parser::yes },
+ { 'C', OPT_INDEXFILE, Arg_parser::no },
+ { 'd', OPT_DOC_TITLE, Arg_parser::yes },
+ { 'D', OPT_DATADIR, Arg_parser::yes },
+ { 'e', OPT_STYLE_IN, Arg_parser::yes },
+ { 'E', OPT_ADDDATADIR, Arg_parser::yes },
+ { 'f', OPT_FRAGMENT, Arg_parser::no },
+ { 'F', OPT_FORMAT, Arg_parser::yes },
+ { S_OPT_CLASSNAME, OPT_CLASSNAME, Arg_parser::yes },
+ { 'h', OPT_HELP, Arg_parser::no },
+ { 'H', OPT_HTML, Arg_parser::no },
+ { 'i', OPT_IN, Arg_parser::yes },
+ { 'I', OPT_INC_STYLE, Arg_parser::no },
+ { 'j', OPT_LNR_LEN, Arg_parser::yes },
+ { 'J', OPT_LINE_LEN, Arg_parser::yes },
+ { 'k', OPT_BASE_FONT, Arg_parser::yes },
+ { 'K', OPT_BASE_FONT_SIZE, Arg_parser::yes },
+ { 'l', OPT_LINENO, Arg_parser::no },
+ { 'L', OPT_LATEX, Arg_parser::no },
+ { 'm', OPT_LNR_START, Arg_parser::yes },
+ { 'M', OPT_XTERM256, Arg_parser::no },
+ { 'n', OPT_ORDERED_LIST, Arg_parser::no },
+ { 'N', OPT_ANCHOR_FN, Arg_parser::no },
+ { 'o', OPT_OUT, Arg_parser::yes },
+ { 'O', OPT_OUTDIR, Arg_parser::yes },
+ { 'p', OPT_LISTLANGS, Arg_parser::no },
+ { 'P', OPT_PROGRESSBAR, Arg_parser::no },
+ { 'q', OPT_QUIET, Arg_parser::no },
+ { 'Q', OPT_VERSION, Arg_parser::no },
+ { 'r', OPT_REPLACE_QUOTES, Arg_parser::no },
+ { 'R', OPT_RTF, Arg_parser::no },
+ { 's', OPT_STYLE, Arg_parser::yes },
+ { 'S', OPT_SYNTAX, Arg_parser::yes },
+ { 't', OPT_DELTABS, Arg_parser::yes },
+ { 'T', OPT_TEX, Arg_parser::no },
+ { 'u', OPT_ENCODING, Arg_parser::yes },
+ { 'v', OPT_VERBOSE, Arg_parser::no },
+ { 'V', OPT_WRAPSIMPLE, Arg_parser::no },
+ { 'w', OPT_LISTTHEMES, Arg_parser::no },
+ { 'W', OPT_WRAP, Arg_parser::no },
+ { 'x', OPT_RTF_PAGE_SIZE, Arg_parser::yes },
+ { 'X', OPT_XHTML, Arg_parser::no },
+ { 'y', OPT_ANCHOR_PFX, Arg_parser::yes },
+ { 'z', OPT_FILLZEROES, Arg_parser::no },
+ { 'Z', OPT_XML, Arg_parser::no },
+ { 'G', OPT_SVG, Arg_parser::no },
+ { 'Y', OPT_BBCODE, Arg_parser::no },
+ { S_OPT_SVG_WIDTH, OPT_SVG_WIDTH, Arg_parser::yes },
+ { S_OPT_SVG_HEIGHT, OPT_SVG_HEIGHT, Arg_parser::yes },
+ { S_OPT_ADDCONFDIR, OPT_ADDCONFDIR, Arg_parser::yes },
+ { S_OPT_ENCLOSE_PRE, OPT_ENCLOSE_PRE, Arg_parser::no },
+ { S_OPT_FORCE_OUTPUT, OPT_FORCE_OUTPUT, Arg_parser::no },
+ { S_OPT_INLINE_CSS, OPT_INLINE_CSS, Arg_parser::no },
+ { S_OPT_KW_CASE, OPT_KW_CASE, Arg_parser::yes },
+ { S_OPT_MARK_LINES, OPT_MARK_LINES, Arg_parser::yes },
+ { S_OPT_PRINT_CONFIG, OPT_PRINT_CONFIG, Arg_parser::no },
+ { S_OPT_TEST_INPUT, OPT_TEST_INPUT, Arg_parser::no },
+ { S_OPT_RTF_CHAR_STYLES, OPT_RTF_CHAR_STYLES, Arg_parser::no },
+ { S_OPT_SKIP_UNKNOWN, OPT_SKIP_UNKNOWN, Arg_parser::yes },
+ { S_OPT_CTAGS_FILE, OPT_CTAGS_FILE, Arg_parser::maybe },
+ { S_OPT_START_NESTED, OPT_START_NESTED, Arg_parser::yes },
+ { S_OPT_COMPAT_DOC, OPT_COMPAT_DOC, Arg_parser::no },
+ { S_OPT_COMPAT_NODOC, OPT_COMPAT_NODOC, Arg_parser::no },
+ { S_OPT_COMPAT_TAB, OPT_COMPAT_TAB, Arg_parser::yes },
+ { S_OPT_COMPAT_CSS, OPT_COMPAT_CSS, Arg_parser::yes },
+ { S_OPT_COMPAT_OUTDIR, OPT_COMPAT_OUTDIR, Arg_parser::yes },
+ { S_OPT_COMPAT_FAILSAFE, OPT_COMPAT_FAILSAFE, Arg_parser::no },
+ { S_OPT_COMPAT_OUTFORMAT, OPT_COMPAT_OUTFORMAT, Arg_parser::yes },
+ { S_OPT_COMPAT_SRCLANG, OPT_COMPAT_SRCLANG, Arg_parser::yes },
+ { S_OPT_COMPAT_LINENUM, OPT_COMPAT_LINENUM, Arg_parser::maybe },
+ { S_OPT_COMPAT_LINEREF, OPT_COMPAT_LINEREF, Arg_parser::maybe },
+ { S_OPT_PRETTY_SYMBOLS, OPT_PRETTY_SYMBOLS, Arg_parser::no },
+ { S_OPT_EOL_DELIM_CR, OPT_EOL_DELIM_CR, Arg_parser::no },
+ { S_OPT_PRINT_STYLE, OPT_PRINT_STYLE, Arg_parser::no },
+ { S_OPT_NO_TRAILING_NL, OPT_NO_TRAILING_NL, Arg_parser::no },
+
+ { 0, 0, Arg_parser::no }
+ };
+
+
+ Arg_parser parser ( argc, argv, options );
+ if ( parser.error().size() ) // bad option
+ {
+ cerr << "highlight: "<< parser.error() <<"\n";
+ cerr << "Try `highlight --help' for more information.\n";
+ exit ( 1 );
+ }
+
+ int argind = 0;
+ for ( ; argind < parser.arguments(); ++argind )
+ {
+ const int code = parser.code ( argind );
+ const std::string & arg = parser.argument ( argind );
+ if ( !code ) break; // no more options
+ switch ( code )
+ {
+ case 'a':
+ opt_attach_line_anchors = true;
+ break;
+ case 'A':
+ outputType=highlight::ANSI;
+ break;
+ case 'b':
+ opt_babel=true;
+ break;
+ case 'B':
+ opt_batch_mode = true;
+ readDirectory ( arg );
+ break;
+ case 'c':
+ case S_OPT_COMPAT_CSS:
+ styleOutFilename = arg;
+ opt_stylepath_explicit=true;
+ break;
+ case 'C':
+ opt_printindex=true;
+ break;
+ case 'd':
+ docTitle = arg;
+ break;
+ case 'D':
+ dataDir=validateDirPath ( arg );
+ break;
+ case 'e':
+ styleInFilename = arg;
+ break;
+ case 'E':
+ additionalDataDir=validateDirPath ( arg );
+ break;
+ case 'f':
+ case S_OPT_COMPAT_NODOC:
+ opt_fragment = true;
+ break;
+ case 'F':
+ indentScheme = arg;
+ break;
+ case S_OPT_CLASSNAME:
+ className = arg;
+ break;
+ case 'h':
+ opt_help = true;
+ break;
+ case 'H':
+ outputType=highlight::HTML;
+ break;
+ case 'i':
+ inputFileNames.push_back ( arg );
+ break;
+ case 'I':
+ opt_include_style = true;
+ break;
+ case 'j':
+ StringTools::str2num<int> ( lineNrWidth, arg, std::dec );
+ break;
+ case 'J':
+ StringTools::str2num<int> ( lineLength, arg, std::dec );
+ break;
+ case 'k':
+ baseFont = arg;
+ break;
+ case 'K':
+ baseFontSize = arg;
+ break;
+ case S_OPT_COMPAT_LINENUM:
+ if ( arg=="0" ) opt_fill_zeroes=true;
+ case 'l':
+ opt_linenumbers = true;
+ break;
+ case 'L':
+ outputType=highlight::LATEX;
+ break;
+ case 'm':
+ StringTools::str2num<int> ( lineNrStart, arg, std::dec );
+ break;
+ case 'M':
+ outputType=highlight::XTERM256;
+ break;
+ case 'n':
+ opt_ordered_list = opt_linenumbers = true;
+ break;
+ case 'N':
+ opt_fnames_as_anchors=true;
+ break;
+ case 'o':
+ outFilename = arg;
+ break;
+ case 'O':
+ case S_OPT_COMPAT_OUTDIR:
+ outDirectory = validateDirPath ( arg );
+ break;
+ case 'p':
+ opt_show_langdefs = true;
+ break;
+ case 'P':
+ opt_print_progress=true;
+ break;
+ case 'q':
+ opt_quiet = true;
+ break;
+ case 'Q':
+ opt_version = true;
+ break;
+ case 'r':
+ opt_replacequotes=true;
+ break;
+ case 'R':
+ outputType=highlight::RTF;
+ break;
+ case 's':
+ styleName = arg;
+ opt_style = true;
+ break;
+ case 'S':
+ case S_OPT_COMPAT_SRCLANG:
+ syntax = arg;
+ opt_syntax = true;
+ break;
+ case 't':
+ case S_OPT_COMPAT_TAB:
+ StringTools::str2num<int> ( numberSpaces, arg, std::dec );
+ break;
+ case 'T':
+ outputType=highlight::TEX;
+ break;
+ case 'u':
+ encodingName = arg;
+ break;
+ case 'v':
+ opt_verbose = true;
+ break;
+ case 'V':
+ wrappingStyle = highlight::WRAP_SIMPLE;
+ break;
+ case 'w':
+ opt_show_themes = true;
+ break;
+ case 'W':
+ wrappingStyle = highlight::WRAP_DEFAULT;
+ break;
+ case 'x':
+ pageSize = arg;
+ break;
+ case 'X':
+ outputType=highlight::XHTML;
+ break;
+ case 'y':
+ anchorPrefix = arg;
+ break;
+ case 'z':
+ opt_fill_zeroes=true;
+ break;
+ case 'Z':
+ outputType=highlight::XML;
+ break;
+ case 'G':
+ outputType=highlight::SVG;
+ break;
+ case 'Y':
+ outputType=highlight::BBCODE;
+ break;
+ case S_OPT_SVG_WIDTH:
+ svg_width = arg;
+ break;
+ case S_OPT_SVG_HEIGHT:
+ svg_height = arg;
+ break;
+ case S_OPT_ADDCONFDIR:
+ additionalConfigDir = validateDirPath ( arg );
+ break;
+ case S_OPT_ENCLOSE_PRE:
+ opt_enclose_pre=true;
+ break;
+ case S_OPT_FORCE_OUTPUT:
+ case S_OPT_COMPAT_FAILSAFE:
+ opt_force_output = true;
+ break;
+ case S_OPT_INLINE_CSS:
+ opt_inline_css=true;
+ break;
+ case S_OPT_KW_CASE:
+ {
+ const string tmp = StringTools::change_case ( arg );
+ if ( tmp == "upper" )
+ keywordCase = StringTools::CASE_UPPER;
+ else if ( tmp == "lower" )
+ keywordCase = StringTools::CASE_LOWER;
+ else if ( tmp == "capitalize" )
+ keywordCase = StringTools::CASE_CAPITALIZE;
+ }
+ break;
+ case S_OPT_COMPAT_OUTFORMAT:
+ {
+ const string tmp = StringTools::change_case ( arg );
+ if ( tmp == "xhtml" )
+ outputType = highlight::XHTML;
+ else if ( tmp == "tex" )
+ outputType = highlight::TEX;
+ else if ( tmp == "latex" )
+ outputType = highlight::LATEX;
+ else if ( tmp == "rtf" )
+ outputType = highlight::RTF;
+ else if ( tmp == "xml" )
+ outputType = highlight::XML;
+ else if ( tmp == "ansi" || tmp == "esc" ) // gnu source-highlight esc parameter
+ outputType = highlight::ANSI;
+ else if ( tmp == "xterm256" )
+ outputType = highlight::XTERM256;
+ else if ( tmp == "svg" )
+ outputType = highlight::SVG;
+ else if ( tmp == "bbcode" )
+ outputType = highlight::BBCODE;
+ else
+ outputType = highlight::HTML;
+ }
+ break;
+ case S_OPT_MARK_LINES:
+ markLinesArg = arg;
+ break;
+ case S_OPT_PRINT_CONFIG:
+ opt_print_config = true;
+ break;
+ case S_OPT_TEST_INPUT:
+ opt_validate=true;
+ break;
+ case S_OPT_RTF_CHAR_STYLES:
+ opt_char_styles=true;
+ break;
+ case S_OPT_SKIP_UNKNOWN:
+ skipArg=arg;
+ break;
+ case S_OPT_CTAGS_FILE:
+ ctagsFile = ( arg.empty() ) ? "tags" :arg;
+ break;
+ case S_OPT_PRETTY_SYMBOLS:
+ opt_pretty_symbols = true;
+ break;
+ case S_OPT_COMPAT_DOC:
+ opt_fragment = false;
+ break;
+ case S_OPT_COMPAT_LINEREF:
+ opt_linenumbers = true;
+ opt_attach_line_anchors = true;
+ anchorPrefix = ( arg.empty() ) ? "line":arg;
+ break;
+ case S_OPT_EOL_DELIM_CR:
+ opt_delim_CR = true;
+ break;
+ case S_OPT_START_NESTED:
+ startNestedLang=arg;
+ break;
+ case S_OPT_PRINT_STYLE:
+ opt_print_style = true;
+ break;
+ case S_OPT_NO_TRAILING_NL:
+ opt_no_trailing_nl = true;
+ break;
+ default:
+ cerr << "highlight: option parsing failed" << endl;
+ }
+ }
+
+ if ( argind < parser.arguments() ) //still args left
+ {
+ if ( inputFileNames.empty() )
+ {
+ while ( argind < parser.arguments() )
+ {
+ inputFileNames.push_back ( parser.argument ( argind++ ) );
+ }
+ }
+ }
+ else if ( inputFileNames.empty() )
+ {
+ inputFileNames.push_back ( "" );
+ }
+ if ( printDebugInfo() && configFileRead )
+ {
+ cout << "Configuration file \""<<configFilePath<<"\" was read.\n";
+ }
+
+ if ( skipArg.size() )
+ {
+ istringstream valueStream;
+ string elem;
+ string wildcard;
+ valueStream.str ( StringTools::change_case ( skipArg,StringTools::CASE_LOWER ) );
+
+ while ( getline ( valueStream, elem, ';' ) )
+ {
+ ignoredFileTypes.insert ( elem );
+ }
+ for ( vector<string>::iterator file=inputFileNames.begin();file!=inputFileNames.end();file++ )
+ {
+ for ( set<string>::iterator ext=ignoredFileTypes.begin();ext!=ignoredFileTypes.end();ext++ )
+ {
+ wildcard="*."+*ext;
+ if ( Platform::wildcmp ( wildcard.c_str(), ( *file ).c_str() ) )
+ {
+ inputFileNames.erase ( file );
+ file--;
+ break;
+ }
+ }
+ }
+ }
+}
+
+CmdLineOptions::~CmdLineOptions() {}
+
+const string &CmdLineOptions::getSingleOutFilename()
+{
+ if ( !inputFileNames.empty() && !outDirectory.empty() )
+ {
+ if ( outFilename.empty() )
+ {
+ outFilename = outDirectory;
+ int delim = getSingleInFilename().find_last_of ( Platform::pathSeparator ) +1;
+ outFilename += getSingleInFilename().substr ( ( delim>-1 ) ?delim:0 )
+ + getOutFileSuffix();
+ }
+ }
+ return outFilename;
+}
+
+const string &CmdLineOptions::getSingleInFilename() const
+{
+ return inputFileNames[0];
+}
+
+const string &CmdLineOptions::getOutDirectory()
+{
+ if ( !outFilename.empty() && !enableBatchMode() )
+ {
+ outDirectory=getDirName ( outFilename );
+ }
+ return outDirectory;
+}
+
+const string CmdLineOptions::getStyleOutFilename() const
+{
+ if ( !styleOutFilename.empty() ) return styleOutFilename;
+
+ if ( outputType==highlight::TEX || outputType==highlight::LATEX )
+ {
+ return "highlight.sty";
+ }
+ else
+ {
+ return "highlight.css";
+ }
+}
+const string &CmdLineOptions::getStyleInFilename() const
+{
+ return styleInFilename;
+}
+const string& CmdLineOptions::getSVGWidth() const
+{
+ return svg_width;
+}
+const string& CmdLineOptions::getSVGHeight() const
+{
+ return svg_height;
+}
+int CmdLineOptions::getNumberSpaces() const
+{
+ return numberSpaces;
+}
+bool CmdLineOptions::printVersion() const
+{
+ return opt_version;
+}
+bool CmdLineOptions::printHelp() const
+{
+ return opt_help;
+}
+bool CmdLineOptions::printDebugInfo() const
+{
+ return opt_verbose;
+}
+bool CmdLineOptions::printConfigInfo() const
+{
+ return opt_print_config;
+}
+bool CmdLineOptions::quietMode() const
+{
+ return opt_quiet;
+}
+bool CmdLineOptions::includeStyleDef() const
+{
+ return opt_include_style;
+}
+bool CmdLineOptions::useFNamesAsAnchors() const
+{
+ return opt_fnames_as_anchors;
+}
+
+bool CmdLineOptions::formatSupportsExtStyle()
+{
+ return outputType==highlight::HTML ||
+ outputType==highlight::XHTML ||
+ outputType==highlight::LATEX ||
+ outputType==highlight::TEX ||
+ outputType==highlight::SVG;
+}
+
+bool CmdLineOptions::printLineNumbers() const
+{
+ return opt_linenumbers;
+}
+
+string CmdLineOptions::getThemeName() const
+{
+ return ( ( opt_style ) ? styleName+".style" : "kwrite.style" );
+}
+bool CmdLineOptions::enableBatchMode() const
+{
+ return inputFileNames.size() >1 || opt_batch_mode;
+}
+bool CmdLineOptions::fragmentOutput() const
+{
+ return opt_fragment;
+}
+string CmdLineOptions::getOutFileSuffix() const
+{
+ switch ( outputType )
+ {
+ case highlight::XHTML: return ".xhtml";
+ case highlight::RTF: return ".rtf";
+ case highlight::TEX:
+ case highlight::LATEX: return ".tex";
+ case highlight::XML: return ".xml";
+ case highlight::SVG: return ".svg";
+ case highlight::ANSI: return ".ansi";
+ case highlight::XTERM256: return ".xterm";
+ case highlight::BBCODE: return ".bbcode";
+ default: return ".html";
+ }
+}
+string CmdLineOptions::getDirName ( const string & path )
+{
+ size_t dirNameLength=path.rfind ( Platform::pathSeparator );
+ return ( dirNameLength==string::npos ) ?string() :path.substr ( 0, dirNameLength+1 );
+}
+bool CmdLineOptions::attachLineAnchors() const
+{
+ return opt_attach_line_anchors;
+}
+bool CmdLineOptions::showThemes() const
+{
+ return opt_show_themes;
+}
+bool CmdLineOptions::showLangdefs() const
+{
+ return opt_show_langdefs;
+}
+bool CmdLineOptions::outDirGiven() const
+{
+ return !outFilename.empty();
+}
+bool CmdLineOptions::replaceQuotes() const
+{
+ return opt_replacequotes;
+}
+bool CmdLineOptions::disableBabelShorthands() const
+{
+ return opt_babel;
+}
+bool CmdLineOptions::prettySymbols() const
+{
+ return opt_pretty_symbols;
+}
+bool CmdLineOptions::getFlag ( const string& paramVal )
+{
+ return StringTools::change_case ( paramVal ) =="true";
+}
+/*
+bool CmdLineOptions::formattingEnabled(){
+ return !indentScheme.empty();
+}
+*/
+bool CmdLineOptions::orderedList() const
+{
+ return opt_ordered_list;
+}
+bool CmdLineOptions::useCRDelimiter() const {
+ return opt_delim_CR;
+}
+const string &CmdLineOptions::getDataDir() const
+{
+ return dataDir;
+}
+bool CmdLineOptions::printOnlyStyle() const {
+ return opt_print_style;
+}
+
+string CmdLineOptions::getIndentScheme() const
+{
+ return StringTools::change_case ( indentScheme );
+}
+
+const string &CmdLineOptions::getAdditionalDataDir() const
+{
+ return additionalDataDir;
+}
+const string &CmdLineOptions::getAdditionalConfDir() const
+{
+ return additionalConfigDir;
+}
+const string &CmdLineOptions::getLanguage() const
+{
+ return syntax;
+}
+const string&CmdLineOptions::getEncoding() const
+{
+ return encodingName;
+}
+
+const string& CmdLineOptions::getAnchorPrefix() const
+{
+ return anchorPrefix;
+}
+
+const string &CmdLineOptions::getPageSize() const
+{
+ return pageSize;
+}
+bool CmdLineOptions::printIndexFile() const
+{
+ return opt_printindex && ( outputType==highlight::HTML ||
+ outputType==highlight::XHTML );
+}
+bool CmdLineOptions::printProgress() const
+{
+ return opt_print_progress;
+}
+bool CmdLineOptions::fillLineNrZeroes() const
+{
+ return opt_fill_zeroes;
+}
+bool CmdLineOptions::syntaxGiven() const
+{
+ return opt_syntax;
+}
+bool CmdLineOptions::omitEncoding() const
+{
+ return StringTools::change_case ( encodingName ) =="none";
+}
+bool CmdLineOptions::forceOutput() const
+{
+ return opt_force_output;
+}
+bool CmdLineOptions::validateInput() const
+{
+ return opt_validate;
+}
+bool CmdLineOptions::inlineCSS() const
+{
+ return opt_inline_css;
+}
+bool CmdLineOptions::enclosePreTag() const
+{
+ return opt_enclose_pre;
+}
+bool CmdLineOptions::includeCharStyles() const
+{
+ return opt_char_styles;
+}
+bool CmdLineOptions::disableTrailingNL() const
+{
+ return opt_no_trailing_nl;
+}
+const string &CmdLineOptions::getConfigFilePath() const
+{
+ return configFilePath;
+}
+
+const string& CmdLineOptions::getDocumentTitle() const
+{
+ return docTitle;
+}
+
+highlight::WrapMode CmdLineOptions::getWrappingStyle() const
+{
+ return wrappingStyle;
+}
+const vector <string> & CmdLineOptions::getInputFileNames() const
+{
+ return inputFileNames;
+}
+
+const map <int,string> & CmdLineOptions::getMarkLines()
+{
+ markLines.clear();
+ istringstream valueStream;
+ string elem;
+ size_t delimPos;
+ int markLineNo;
+ valueStream.str ( markLinesArg );
+ // Format: "1=help line one; 3=help line three; 5 "
+ while ( getline ( valueStream, elem, ';' ) )
+ {
+ delimPos = elem.find ( '=' );
+ markLineNo=0;
+ StringTools::str2num<int> ( markLineNo, elem.substr ( 0,delimPos ), std::dec );
+ if ( markLineNo )
+ {
+ markLines[markLineNo] =
+ ( delimPos!=string::npos ) ?elem.substr ( delimPos+1 ) :"";
+ }
+ }
+ return markLines;
+}
+void CmdLineOptions::readDirectory ( const string & wildcard )
+{
+ // get matching files, use recursive search
+ bool directoryOK=Platform::getDirectoryEntries ( inputFileNames, wildcard, true );
+ if ( !directoryOK )
+ {
+ cerr << "highlight: No files matched the pattern \""
+ << wildcard << "\"."<< endl;
+ }
+}
+
+string CmdLineOptions::validateDirPath ( const string & path )
+{
+ return ( path[path.length()-1] !=Platform::pathSeparator ) ?
+ path+Platform::pathSeparator : path;
+}
+
+highlight::OutputType CmdLineOptions::getOutputType() const
+{
+ return outputType;
+}
+
+StringTools::KeywordCase CmdLineOptions::getKeywordCase() const
+{
+ return keywordCase;
+}
+
+bool CmdLineOptions::hasBaseFont() const
+{
+ return ( ! baseFont.empty() ) ;
+}
+
+const string& CmdLineOptions::getBaseFont() const
+{
+ return baseFont ;
+}
+
+bool CmdLineOptions::hasBaseFontSize() const
+{
+ return ( ! baseFontSize.empty() ) ;
+}
+
+const string& CmdLineOptions::getBaseFontSize() const
+{
+ return baseFontSize ;
+}
+
+const string& CmdLineOptions::getClassName() const
+{
+ return className ;
+}
+
+const string& CmdLineOptions::getTagsFile() const
+{
+ return ctagsFile;
+}
+const string& CmdLineOptions::getStartNestedLang() const
+{
+ return startNestedLang;
+}
+int CmdLineOptions::getNumberWidth()
+{
+ return lineNrWidth;
+}
+
+int CmdLineOptions::getLineLength()
+{
+ return lineLength;
+}
+
+int CmdLineOptions::getNumberStart()
+{
+ return lineNrStart;
+}
+
+void CmdLineOptions::loadConfigurationFile()
+{
+#ifndef _WIN32
+#ifdef CONFIG_FILE_PATH
+ configFilePath=CONFIG_FILE_PATH;
+#else
+ char* homeEnv=getenv ( "HOME" );
+ if ( homeEnv==NULL ) return;
+ configFilePath=string ( homeEnv ) +"/.highlightrc";
+#endif
+#else
+ configFilePath = Platform::getAppPath() + "highlight.conf";
+#endif
+ ConfigurationReader userConfig ( configFilePath );
+
+ if ( userConfig.found() )
+ {
+ string paramVal;
+ configFileRead=true;
+
+ styleOutFilename = userConfig.getParameter ( OPT_STYLE_OUT );
+ styleInFilename = userConfig.getParameter ( OPT_STYLE_IN );
+ styleName = userConfig.getParameter ( OPT_STYLE );
+ opt_style = !styleName.empty();
+ syntax = userConfig.getParameter ( OPT_SYNTAX );
+ opt_syntax = !syntax.empty();
+ StringTools::str2num<int> ( numberSpaces, userConfig.getParameter ( OPT_DELTABS ), std::dec );
+ indentScheme = userConfig.getParameter ( OPT_FORMAT );
+ baseFontSize = userConfig.getParameter ( OPT_BASE_FONT_SIZE );
+ baseFont = userConfig.getParameter ( OPT_BASE_FONT );
+ skipArg = userConfig.getParameter ( OPT_SKIP_UNKNOWN );
+
+ paramVal = userConfig.getParameter ( OPT_DATADIR );
+ if ( !paramVal.empty() )
+ {
+ dataDir=validateDirPath ( paramVal );
+ }
+ paramVal = userConfig.getParameter ( OPT_ADDDATADIR );
+ if ( !paramVal.empty() )
+ {
+ additionalDataDir=validateDirPath ( paramVal );
+ }
+ paramVal = userConfig.getParameter ( OPT_ADDCONFDIR );
+ if ( !paramVal.empty() )
+ {
+ additionalConfigDir=validateDirPath ( paramVal );
+ }
+ paramVal = userConfig.getParameter ( OPT_OUTDIR );
+ if ( !paramVal.empty() )
+ {
+ outDirectory=validateDirPath ( paramVal );
+ }
+ paramVal = userConfig.getParameter ( OPT_ENCODING );
+ if ( !paramVal.empty() )
+ {
+ encodingName=paramVal;
+ }
+ paramVal = userConfig.getParameter ( OPT_LNR_LEN );
+ if ( !paramVal.empty() )
+ {
+ StringTools::str2num<int> ( lineNrWidth, string ( paramVal ), std::dec );
+ }
+ paramVal = userConfig.getParameter ( OPT_LNR_START );
+ if ( !paramVal.empty() )
+ {
+ StringTools::str2num<int> ( lineNrStart, string ( paramVal ), std::dec );
+ }
+ paramVal = userConfig.getParameter ( OPT_ANCHOR_PFX );
+ if ( !paramVal.empty() )
+ {
+ anchorPrefix=paramVal;
+ }
+
+ opt_include_style=getFlag ( userConfig.getParameter ( OPT_INC_STYLE ) );
+ opt_verbose=getFlag ( userConfig.getParameter ( OPT_VERBOSE ) );
+ opt_ordered_list=getFlag ( userConfig.getParameter ( OPT_ORDERED_LIST ) );
+ opt_linenumbers=opt_ordered_list || getFlag ( userConfig.getParameter ( OPT_LINENO ) );
+ opt_fragment=getFlag ( userConfig.getParameter ( OPT_FRAGMENT ) );
+ opt_attach_line_anchors=getFlag ( userConfig.getParameter ( OPT_ANCHORS ) );
+ opt_printindex=getFlag ( userConfig.getParameter ( OPT_INDEXFILE ) );
+ opt_quiet=getFlag ( userConfig.getParameter ( OPT_QUIET ) );
+ opt_replacequotes=getFlag ( userConfig.getParameter ( OPT_REPLACE_QUOTES ) );
+ opt_print_progress=getFlag ( userConfig.getParameter ( OPT_PROGRESSBAR ) );
+ opt_fill_zeroes=getFlag ( userConfig.getParameter ( OPT_FILLZEROES ) );
+ opt_fnames_as_anchors=getFlag ( userConfig.getParameter ( OPT_ANCHOR_FN ) );
+ opt_validate=getFlag ( userConfig.getParameter ( OPT_TEST_INPUT ) );
+ opt_fnames_as_anchors=getFlag ( userConfig.getParameter ( OPT_ANCHOR_FN ) );
+ opt_inline_css=getFlag ( userConfig.getParameter ( OPT_INLINE_CSS ) );
+ opt_delim_CR=getFlag ( userConfig.getParameter ( OPT_EOL_DELIM_CR) );
+
+ if ( getFlag ( userConfig.getParameter ( OPT_WRAP ) ) )
+ {
+ wrappingStyle=highlight::WRAP_DEFAULT;
+ }
+ if ( getFlag ( userConfig.getParameter ( OPT_WRAPSIMPLE ) ) )
+ {
+ wrappingStyle=highlight::WRAP_SIMPLE;
+ }
+ if ( getFlag ( userConfig.getParameter ( OPT_XHTML ) ) )
+ {
+ outputType=highlight::XHTML;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_RTF ) ) )
+ {
+ outputType=highlight::RTF;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_TEX ) ) )
+ {
+ outputType=highlight::TEX;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_LATEX ) ) )
+ {
+ outputType=highlight::LATEX;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_ANSI ) ) )
+ {
+ outputType=highlight::ANSI;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_XML ) ) )
+ {
+ outputType=highlight::XML;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_SVG ) ) )
+ {
+ outputType=highlight::SVG;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_XTERM256 ) ) )
+ {
+ outputType=highlight::XTERM256;
+ }
+ else if ( getFlag ( userConfig.getParameter ( OPT_BBCODE) ) )
+ {
+ outputType=highlight::BBCODE;
+ }
+ }
+}
+
diff --git a/support/highlight/src/cli/cmdlineoptions.h b/support/highlight/src/cli/cmdlineoptions.h
new file mode 100644
index 0000000000..c4cbe26b6d
--- /dev/null
+++ b/support/highlight/src/cli/cmdlineoptions.h
@@ -0,0 +1,471 @@
+/***************************************************************************
+ cmdlineoptions.h - description
+ -------------------
+ begin : Sun Nov 25 2001
+ copyright : (C) 2001-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef CMDLINEOPTIONS_H
+#define CMDLINEOPTIONS_H
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#include <string>
+#include <map>
+#include <set>
+#include <cstdlib>
+#include <iostream>
+#include <fstream>
+#include <vector>
+
+#include "stringtools.h"
+#include "enums.h"
+
+
+#define OPT_ADDCONFDIR "add-config-dir"
+#define OPT_ADDDATADIR "add-data-dir"
+#define OPT_ANCHORS "anchors"
+#define OPT_ANCHOR_FN "anchor-filename"
+#define OPT_ANCHOR_PFX "anchor-prefix"
+#define OPT_ANSI "ansi"
+#define OPT_BABEL "babel"
+#define OPT_BASE_FONT "font"
+#define OPT_BASE_FONT_SIZE "font-size"
+#define OPT_BATCHREC "batch-recursive"
+#define OPT_CLASSNAME "class-name"
+#define OPT_DATADIR "data-dir"
+#define OPT_DELTABS "replace-tabs"
+#define OPT_DOC_TITLE "doc-title"
+#define OPT_ENCLOSE_PRE "enclose-pre"
+#define OPT_ENCODING "encoding"
+#define OPT_FILLZEROES "zeroes"
+#define OPT_FORCE_OUTPUT "force"
+#define OPT_FORMAT "reformat"
+#define OPT_FRAGMENT "fragment"
+#define OPT_HELP "help"
+#define OPT_HTML "html"
+#define OPT_IN "input"
+#define OPT_INC_STYLE "include-style"
+#define OPT_INDEXFILE "print-index"
+#define OPT_INLINE_CSS "inline-css"
+#define OPT_KW_CASE "kw-case"
+#define OPT_LATEX "latex"
+#define OPT_LINENO "linenumbers"
+#define OPT_LINE_LEN "line-length"
+#define OPT_LISTLANGS "list-langs"
+#define OPT_LISTTHEMES "list-themes"
+#define OPT_LNR_LEN "line-number-length"
+#define OPT_LNR_START "line-number-start"
+#define OPT_MARK_LINES "mark-line"
+#define OPT_ORDERED_LIST "ordered-list"
+#define OPT_OUT "output"
+#define OPT_OUTDIR "outdir"
+#define OPT_RTF_PAGE_SIZE "page-size"
+#define OPT_RTF_CHAR_STYLES "char-styles"
+#define OPT_PRINT_CONFIG "print-config"
+#define OPT_PROGRESSBAR "progress"
+#define OPT_QUIET "quiet"
+#define OPT_REPLACE_QUOTES "replace-quotes"
+#define OPT_RTF "rtf"
+#define OPT_STYLE "style"
+#define OPT_STYLE_IN "style-infile"
+#define OPT_STYLE_OUT "style-outfile"
+#define OPT_SYNTAX "syntax"
+#define OPT_TEST_INPUT "validate-input"
+#define OPT_TEX "tex"
+#define OPT_VERBOSE "verbose"
+#define OPT_VERSION "version"
+#define OPT_WRAP "wrap"
+#define OPT_WRAPSIMPLE "wrap-simple"
+#define OPT_XHTML "xhtml"
+#define OPT_XML "xml"
+#define OPT_XTERM256 "xterm256"
+#define OPT_SVG "svg"
+#define OPT_SVG_WIDTH "width"
+#define OPT_SVG_HEIGHT "height"
+#define OPT_SKIP_UNKNOWN "skip"
+#define OPT_CTAGS_FILE "ctags-file"
+#define OPT_PRETTY_SYMBOLS "pretty-symbols"
+#define OPT_EOL_DELIM_CR "delim-cr"
+#define OPT_BBCODE "bbcode"
+#define OPT_START_NESTED "start-nested"
+#define OPT_PRINT_STYLE "print-style"
+#define OPT_NO_TRAILING_NL "no-trailing-nl"
+
+// Improve CLI option compatibility with GNU source-highlight
+#define OPT_COMPAT_DOC "doc"
+#define OPT_COMPAT_NODOC "no-doc"
+#define OPT_COMPAT_TAB "tab"
+#define OPT_COMPAT_CSS "css"
+#define OPT_COMPAT_OUTDIR "output-dir"
+#define OPT_COMPAT_FAILSAFE "failsafe"
+#define OPT_COMPAT_OUTFORMAT "out-format"
+#define OPT_COMPAT_SRCLANG "src-lang"
+#define OPT_COMPAT_LINENUM "line-number"
+#define OPT_COMPAT_LINEREF "line-number-ref"
+
+using namespace std;
+
+/// handle command line options
+
+class CmdLineOptions
+{
+ public:
+
+ /**Constructor
+ \param argc Argument count
+ \param argv Argument strings
+ */
+ CmdLineOptions ( const int argc, const char *argv[] );
+ ~CmdLineOptions();
+
+ /** \return Single output file name*/
+ const string &getSingleOutFilename();
+
+ /** \return Single input file name*/
+ const string &getSingleInFilename() const;
+
+ /** \return Output directory*/
+ const string& getOutDirectory() ;
+
+ /** \return Style output file name*/
+ const string getStyleOutFilename() const;
+
+ /** \return Style input file name*/
+ const string& getStyleInFilename() const;
+
+ /** \return Char set*/
+ const string& getEncoding() const;
+
+ /** \return SVG width*/
+ const string& getSVGWidth() const;
+
+ /** \return SVG height*/
+ const string& getSVGHeight() const;
+
+ /** \return Number of spaces to replace a tab*/
+ int getNumberSpaces() const;
+
+ /** \return True if version information should be printed*/
+ bool printVersion() const;
+
+ /** \return True if help information should be printed*/
+ bool printHelp() const;
+
+ /** \return True if debug information should be printed*/
+ bool printDebugInfo() const;
+
+ /** \return True if configuration information should be printed*/
+ bool printConfigInfo() const;
+
+ /** \return True if Style definition should be included in output*/
+ bool includeStyleDef() const;
+
+ /** \return True if line numbers should be printed*/
+ bool printLineNumbers() const;
+
+ /** \return True if CR is eol delimiter */
+ bool useCRDelimiter() const;
+
+ /** \return colour theme name */
+ string getThemeName() const ;
+
+ /** gibt true zurck, falls deutsche Hilfe ausgegeben werden soll */
+ int helpLanguage() const;
+
+ /** \return True if batch mode is active*/
+ bool enableBatchMode() const;
+
+ /** \return True if output shluld be fragmented*/
+ bool fragmentOutput() const;
+
+ /** \return output file suffix */
+ string getOutFileSuffix() const;
+
+ /** \return True if anchors should be attached to line numbers*/
+ bool attachLineAnchors() const;
+
+ /** \return True if list of installed themes should be printed*/
+ bool showThemes() const;
+
+ /** \return True if list of installed language definitions should be printed*/
+ bool showLangdefs() const;
+
+ /** \return True if loutput directory is given*/
+ bool outDirGiven() const;
+
+ /** \return True if refomatting is enabled*/
+// bool formattingEnabled();
+
+ /** \return True if a new data directory is given*/
+ bool dataDirGiven() const;
+
+ /** \return True if an additional data directory is given*/
+ bool additionalDataDirGiven() const;
+
+ /** \return True if index file should be printed*/
+ bool printIndexFile() const;
+
+ /** \return True if quotes should be replaced by /dq in LaTeX*/
+ bool replaceQuotes() const;
+
+ /** \return True if shorthands of LaTeX Babel package should be disabled*/
+ bool disableBabelShorthands() const;
+
+ /** \return True if input file name should be used as anchor name */
+ bool useFNamesAsAnchors() const;
+
+ /** \return Data directory*/
+ const string &getDataDir() const;
+
+ /** \return Additional data directory*/
+ const string &getAdditionalDataDir() const;
+
+ /** \return Additional config data directory*/
+ const string &getAdditionalConfDir() const;
+
+ /** \return path of user config file*/
+ const string &getConfigFilePath() const;
+
+ /** \return True if language syntax is given*/
+ bool syntaxGiven() const;
+
+ /** \return True if quiet mode is active*/
+ bool quietMode() const;
+
+ /** \return True if progress bar should be printed in batch mode */
+ bool printProgress() const;
+
+ /** \return True if line numbers are filled with leading zeroes */
+ bool fillLineNrZeroes() const;
+
+ /** \return programming syntax */
+ const string &getLanguage() const ;
+
+ /** \return Wrapping style*/
+ highlight::WrapMode getWrappingStyle() const;
+
+ /** \return List of input file names*/
+ const vector <string> & getInputFileNames() const;
+
+ /** \return Map of marked lines*/
+ const map <int,string> &getMarkLines();
+
+ /** \return indentation and reformatting scheme*/
+ string getIndentScheme() const;
+
+ /** \return RTF page size */
+ const string &getPageSize() const;
+
+ /** \return Output file format */
+ highlight::OutputType getOutputType() const;
+
+ /** \return True if chosen output format supports referenced style files */
+ bool formatSupportsExtStyle();
+
+ /** \return True if style output path was defined by user*/
+ bool styleOutPathDefined() const
+ {
+ return opt_stylepath_explicit;
+ }
+
+ /** \return True if encoding specification should be omitted in output*/
+ bool omitEncoding() const;
+
+ /** \return True if output should be generated if languege type is unknown*/
+ bool forceOutput() const;
+
+ /** \return True if line numbers should be replaced by ordered list (HTML) */
+ bool orderedList() const;
+
+ /** \return True if a base font has been given */
+ bool hasBaseFont() const ;
+
+ /** \return True if input should be validated */
+ bool validateInput() const ;
+
+ /** \return True if CSS should be outputted within tag elements */
+ bool inlineCSS() const ;
+
+ /** \return True if fragmented html output should be enclosed with pre tags */
+ bool enclosePreTag() const ;
+
+ /** \return True if RTF output should include character styles */
+ bool includeCharStyles() const ;
+
+ /** \return True if LaTeX output should includ fancier symbols */
+ bool prettySymbols() const;
+
+ /** \return True if style should be printed */
+ bool printOnlyStyle() const;
+
+ /** \return The given base font, empty string by default */
+ const string& getBaseFont() const ;
+
+ /** \return Document title */
+ const string& getDocumentTitle() const ;
+
+ /** \return anchor prefix */
+ const string& getAnchorPrefix() const ;
+
+ /** \return class name */
+ const string& getClassName() const ;
+
+ /** \return ctags file name */
+ const string& getTagsFile() const ;
+
+ /** \return True if a base font size has been given */
+ bool hasBaseFontSize() const ;
+
+ /** \return True if trailing nl should be omitted */
+ bool disableTrailingNL() const ;
+
+ /** \return The given base font size, empty string by default */
+ const string& getBaseFontSize() const ;
+
+ /** \return name of nested syntax which starts the input */
+ const string& getStartNestedLang() const ;
+
+ /** \return line number width */
+ int getNumberWidth();
+
+ /** \return line length */
+ int getLineLength();
+
+ /** \return Line number start count */
+ int getNumberStart();
+
+ /** \return Keyword Case (upper, lower, unchanged) */
+ StringTools::KeywordCase getKeywordCase() const;
+
+ bool isSkippedExt ( const string& ext )
+ {
+ return ignoredFileTypes.count ( ext );
+ }
+
+ private:
+
+ int numberSpaces; // number of spaces which replace a tab
+ int lineNrWidth; // width of line number (left padding)
+ int lineLength; // length of line before wrapping
+ int lineNrStart; // line number start count
+ highlight::WrapMode wrappingStyle; // line wrapping mode
+ highlight::OutputType outputType;
+ StringTools::KeywordCase keywordCase;
+
+ // name of single output file
+ string outFilename,
+ // output directory
+ outDirectory,
+ // programming syntax which will be loaded
+ syntax,
+ // name of colour theme
+ styleName,
+ // name of external style file
+ styleOutFilename,
+ // name of file to be included in external style file
+ styleInFilename,
+ // used to define data directories at runtime
+ dataDir, additionalDataDir, additionalConfigDir;
+ // name of indenation scheme
+ string indentScheme,
+ pageSize, startNestedLang;
+
+ string baseFont, baseFontSize;
+ string docTitle, className;
+ string markLinesArg;
+ string skipArg;
+ string svg_height, svg_width;
+ string ctagsFile;
+
+ bool opt_syntax;
+ bool opt_include_style;
+ bool opt_help;
+ bool opt_version ;
+ bool opt_verbose;
+ bool opt_print_config;
+ bool opt_linenumbers;
+ bool opt_style;
+ bool opt_batch_mode;
+ bool opt_fragment;
+ bool opt_attach_line_anchors;
+ bool opt_show_themes;
+ bool opt_show_langdefs;
+ bool opt_asformat_output;
+ bool opt_printindex;
+ bool opt_quiet;
+ bool opt_replacequotes;
+ bool opt_babel;
+ bool opt_print_progress;
+ bool opt_fill_zeroes;
+ bool opt_stylepath_explicit;
+ bool opt_force_output;
+ bool opt_ordered_list;
+ bool opt_fnames_as_anchors;
+ bool opt_validate;
+ bool opt_inline_css;
+ bool opt_enclose_pre;
+ bool opt_char_styles;
+ bool opt_pretty_symbols;
+ bool opt_delim_CR;
+ bool opt_print_style;
+ bool opt_no_trailing_nl;
+
+ bool configFileRead;
+
+ string anchorPrefix;
+
+ string helpLang, encodingName;
+ string configFilePath;
+
+ /** list of all input file names */
+ vector <string> inputFileNames;
+
+ /** list lines which should be marked and supplied with help string */
+ map <int, string> markLines;
+
+ /** list of file types which should be ignored */
+ set <string> ignoredFileTypes;
+
+ /** load highlight configuration file */
+ void loadConfigurationFile();
+
+ /** \return file suffix */
+ string getFileSuffix ( const string & fileName ) const;
+
+ /** \return directory name of path */
+ string getDirName ( const string & path );
+
+ /** get all entries in the directory defined by wildcard */
+ void readDirectory ( const string & wildcard );
+
+ /** \return Boolean value of paramVal */
+ bool getFlag ( const string& paramVal );
+
+ /** \return Valid path name */
+ string validateDirPath ( const string & path );
+};
+
+#endif
diff --git a/support/highlight/src/cli/help.cpp b/support/highlight/src/cli/help.cpp
new file mode 100644
index 0000000000..d80312a7a9
--- /dev/null
+++ b/support/highlight/src/cli/help.cpp
@@ -0,0 +1,185 @@
+/***************************************************************************
+ help.cpp - description
+ -------------------
+ begin : Die Apr 23 2002
+ copyright : (C) 2002-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <iostream>
+
+#include "help.h"
+
+using namespace std;
+
+namespace Help
+{
+
+ void printHelp()
+ {
+ cout<<"USAGE: highlight [OPTIONS]... [FILES]...\n";
+ cout<<"\n";
+ cout<<"General options:\n";
+ cout<<"\n";
+ cout<<" -B, --batch-recursive=<wc> convert all matching files, searches subdirs\n";
+ cout<<" (Example: -B '*.cpp')\n";
+ cout<<" -D, --data-dir=<directory> set path to data directory\n";
+ cout<<" -E, --add-data-dir=<directory> set path to an additional data directory, which\n";
+ cout<<" is searched first\n";
+ cout<<" --add-config-dir=<dir> set path to an additional config directory\n";
+ cout<<" -h, --help print this help\n";
+ cout<<" -i, --input=<file> name of single input file\n";
+ cout<<" -o, --output=<file> name of single output file\n";
+ cout<<" -O, --outdir=<directory> name of output directory\n";
+ cout<<" -p, --list-langs list installed language definitions\n";
+ cout<<" -P, --progress print progress bar in batch mode\n";
+ cout<<" -q, --quiet supress progress info in batch mode\n";
+ cout<<" -S, --syntax=<type> specify type of source code\n";
+ cout<<" -v, --verbose print debug info\n";
+ cout<<" -w, --list-themes list installed colour themes\n";
+ cout<<" --force generate output if language type is unknown\n";
+ cout<<" --print-config print path configuration\n";
+ cout<<" --print-style print only style (see --style-outfile)\n";
+ cout<<" --skip=<list> ignore listed unknown file types\n";
+ cout<<" (Example: --skip='bak;c~;h~')\n";
+ cout<<" --start-nested=<lang> define nested language which starts input\n";
+ cout<<" without opening delimiter\n";
+ cout<<" --validate-input test if input is a valid text file\n";
+ cout<<" --version print version and copyright information\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"Output formats:\n";
+ cout<<"\n";
+ cout<<" -H, --html generate HTML (default)\n";
+ cout<<" -A, --ansi generate terminal output (16 colours)\n";
+ cout<<" -L, --latex generate LaTeX\n";
+ cout<<" -M, --xterm256 generate terminal output (256 colours)\n";
+ cout<<" -R, --rtf generate RTF\n";
+ cout<<" -T, --tex generate TeX\n";
+ cout<<" -X, --xhtml generate XHTML 1.1\n";
+ cout<<" -Z, --xml generate XML\n";
+ cout<<" -G, --svg generate SVG (experimental)\n";
+ cout<<" -Y, --bbcode generate BBCode (experimental)\n";
+ cout<<" --out-format=<format> output file in given format\n";
+ cout<<" <format>: see long options above\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"Output formatting options:\n";
+ cout<<"\n";
+ cout<<" -c, --style-outfile=<file> name of style file or output to stdout, if\n";
+ cout<<" 'stdout' is given as file argument\n";
+ cout<<" -d, --doc-title=<title> document title\n";
+ cout<<" -e, --style-infile=<file> file to be included in style-outfile\n";
+ cout<<" -I, --include-style include style definition\n";
+ cout<<" -f, --fragment omit file header and footer\n";
+ cout<<" -F, --reformat=<style> reformats and indents output in given style\n";
+ cout<<" <style>=['allman', 'banner', 'gnu',\n";
+ cout<<" 'horstmann', 'java', 'kr', 'linux', 'otbs',\n";
+ cout<<" 'stroustrup', 'whitesmith']\n";
+ cout<<" -J, --line-length=<num> line length before wrapping (see -W, -V)\n";
+ cout<<" -j, --line-number-length=<num> line number width incl. left padding\n";
+ cout<<" -k, --font=<font> set font (specific to output format)\n";
+ cout<<" -K, --font-size=<num?> set font size (specific to output format)\n";
+ cout<<" -l, --linenumbers print line numbers in output file\n";
+ cout<<" -m, --line-number-start=<cnt> start line numbering with cnt (assumes -l)\n";
+ cout<<" -s, --style=<style> set colour style (see -w)\n";
+ cout<<" -t, --replace-tabs=<num> replace tabs by <num> spaces\n";
+ cout<<" -u, --encoding=<enc> set output encoding which matches input file\n";
+ cout<<" encoding; omit encoding info if enc=NONE\n";
+ cout<<" -V, --wrap-simple wrap long lines without indenting function\n";
+ cout<<" parameters and statements\n";
+ cout<<" -W, --wrap wrap long lines\n";
+ cout<<" -z, --zeroes fill leading space of line numbers with 0's\n";
+ cout<<" --kw-case=<case> change case of case insensitive keywords\n";
+ cout<<" <case> = ['upper', 'lower', 'capitalize']\n";
+ cout<<" --delim-cr set CR as end-of-line delimiter (MacOS 9)\n";
+ cout<<" --no-trailing-nl omit trailing newline\n";
+ cout<<"\n";
+ cout<<"(X)HTML output options:\n";
+ cout<<"\n";
+ cout<<" -a, --anchors attach anchor to line numbers\n";
+ cout<<" -y, --anchor-prefix=<str> set anchor name prefix\n";
+ cout<<" -N, --anchor-filename use input file name as anchor name\n";
+ cout<<" -C, --print-index print index with hyperlinks to output files\n";
+ cout<<" -n, --ordered-list print lines as ordered list items\n";
+ cout<<" --class-name=<str> set CSS class name prefix\n";
+ cout<<" --inline-css output CSS within each tag (verbose output)\n";
+ cout<<" --mark-line='n[=txt]; m' mark given lines n..m and add optional help\n";
+ cout<<" texts as tooltips\n";
+ cout<<" --enclose-pre enclose fragmented output with pre tag \n";
+ cout<<" (assumes -f)\n";
+ cout<<" --ctags-file[=<file>] read ctags file to include meta information as\n";
+ cout<<" tooltips (default value: tags)\n";
+ cout<<"\n";
+ cout<<"LaTeX output options:\n";
+ cout<<"\n";
+ cout<<" -b, --babel disable Babel package shorthands\n";
+ cout<<" -r, --replace-quotes replace double quotes by \\dq{}\n";
+ cout<<" --pretty-symbols improve appearance of brackets and other symbols\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"RTF output options:\n";
+ cout<<"\n";
+ cout<<" -x, --page-size=<ps> set page size \n";
+ cout<<" <ps> = [a3, a4, a5, b4, b5, b6, letter]\n";
+ cout<<" --char-styles include character stylesheets\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"SVG output options:\n";
+ cout<<"\n";
+ cout<<" --height set image height (units allowed)\n";
+ cout<<" --width set image width (see --height)\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"GNU source-highlight compatibility options:\n";
+ cout<<"\n";
+ cout<<" --doc create stand alone document\n";
+ cout<<" --no-doc cancel the --doc option\n";
+ cout<<" --css=filename the external style sheet filename\n";
+ cout<<" --src-lang=STRING source language\n";
+ cout<<" -t, --tab=INT specify tab length\n";
+ cout<<" -n, --line-number[=0] number all output lines, optional padding\n";
+ cout<<" --line-number-ref[=p] number all output lines and generate an anchor,\n";
+ cout<<" made of the specified prefix p + the line\n";
+ cout<<" number (default='line')\n";
+ cout<<" --output-dir=path output directory\n";
+ cout<<" --failsafe if no language definition is found for the\n";
+ cout<<" input, it is simply copied to the output\n";
+ cout<<"\n";
+ cout<<"\n";
+ cout<<"-t will be ignored if -F is set.\n";
+ cout<<"-i and -o will be ignored if -b or -B is set.\n";
+ cout<<"-r will be ignored if -f is not set.\n";
+ cout<<"-c will be ignored if the output format does not support referenced styles.\n";
+ cout<<"If no in- or output files are specified, stdin and stdout will be used for\n";
+ cout<<"in- or output.\n";
+ cout<<"HTML will be generated, if no other output format is given. Style definitions\n";
+ cout<<"are stored in highlight.css (HTML, XHTML, SVG) or highlight.sty (LaTeX, TeX)\n";
+ cout<<"if neither -c nor -I is given.\n";
+ cout<<"Reformatting code will only work with C, C++, C# and Java input files.\n";
+ cout<<"Wrapping lines with -V or -W will cause faulty highlighting of long single\n";
+ cout<<"line comments and directives. Use with caution.\n";
+ cout<<"\n";
+ cout<<"Updates and information: http://www.andre-simon.de/\n";
+ }
+
+}
diff --git a/support/highlight/src/cli/help.h b/support/highlight/src/cli/help.h
new file mode 100644
index 0000000000..e4500d679c
--- /dev/null
+++ b/support/highlight/src/cli/help.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ help.h - description
+ -------------------
+ begin : Die Apr 23 2002
+ copyright : (C) 2002-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef HELP_H
+#define HELP_H
+
+#include <string>
+
+///Contains methods for printing help messages
+
+namespace Help
+{
+ /** print help message to stdout
+ */
+ void printHelp();
+}
+
+#endif
diff --git a/support/highlight/src/cli/main.cpp b/support/highlight/src/cli/main.cpp
new file mode 100644
index 0000000000..cb2030fdf5
--- /dev/null
+++ b/support/highlight/src/cli/main.cpp
@@ -0,0 +1,709 @@
+/***************************************************************************
+ main.cpp - description
+ -------------------
+ begin : Die Apr 23 22:16:35 CEST 2002
+ copyright : (C) 2002-2009 by Andre Simon
+ email : andre.simon1@gmx.de
+
+ Highlight is a universal source code to HTML converter. Syntax highlighting
+ is formatted by Cascading Style Sheets. It's possible to easily enhance
+ highlight's parsing database.
+
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <memory>
+#include <algorithm>
+#include "main.h"
+#include "re/Pattern.h"
+
+#define MAX_LINE__WIDTH 80
+
+using namespace std;
+
+void HLCmdLineApp::printVersionInfo()
+{
+ cout << "\n highlight version "
+ << HIGHLIGHT_VERSION
+ << "\n Copyright (C) 2002-2010 Andre Simon <andre.simon1 at gmx.de>"
+ << "\n\n Artistic Style Classes (1.24)"
+ << "\n Copyright (C) 2006-2010 by Jim Pattee <jimp03 at email.com>"
+ << "\n Copyright (C) 1998-2002 by Tal Davidson"
+ << "\n\n Regex library (1.09.00)"
+ << "\n Copyright (C) 2003-2008 Jeffery Stuart <stuart at cs.unr.edu>"
+ << "\n\n xterm 256 color matching functions"
+ << "\n Copyright (C) 2006 Wolfgang Frisch <wf at frexx.de>"
+ << "\n\n Argparser class"
+ << "\n Copyright (C) 2006-2008 Antonio Diaz Diaz <ant_diaz at teleline.es>"
+ << "\n\n This software is released under the terms of the GNU General "
+ << "Public License."
+ << "\n For more information about these matters, see the file named "
+ << "COPYING.\n\n";
+}
+
+void HLCmdLineApp::printBadInstallationInfo()
+{
+ cerr << "highlight: Data directory not found ("<<DataDir::LSB_DATA_DIR<<")."
+ " Bad installation or wrong "<< OPT_DATADIR << " parameter."
+ << "\n\nCopy the highlight files into one of the directories listed "
+ << "in INSTALL.\nYou may also set the data directory with "
+ << OPT_DATADIR << " and " << OPT_ADDDATADIR << ".\n";
+}
+
+bool HLCmdLineApp::printInstalledThemes()
+{
+ vector <string> filePaths;
+ string wildcard="*.style";
+ string directory= dataDir.getThemePath();
+ string searchDir = directory + wildcard;
+
+ bool directoryOK = Platform::getDirectoryEntries ( filePaths, searchDir, true );
+ if ( !directoryOK )
+ {
+ cerr << "highlight: Could not access directory "
+ << searchDir
+ << ", aborted.\n";
+ return false;
+ }
+
+ cout << "\nInstalled themes"
+ << " (located in " << directory << "):\n\n";
+
+ sort ( filePaths.begin(), filePaths.end() );
+ string temp;
+
+ for ( unsigned int i=0;i< filePaths.size(); i++ )
+ {
+ temp = ( filePaths[i] ).substr ( directory.length() );
+ cout <<temp.substr ( 1, temp.length()- wildcard.length() ) << endl;
+ }
+ cout <<"\nUse name of the desired theme"
+ << " with the --" OPT_STYLE " option.\n" << endl;
+ return true;
+}
+
+
+bool HLCmdLineApp::printInstalledLanguages()
+{
+ vector <string> filePaths;
+ string wildcard="*.lang";
+ string directory=dataDir.getLangPath();
+ string searchDir = directory + wildcard;
+
+ bool directoryOK = Platform::getDirectoryEntries ( filePaths, searchDir, true );
+ if ( !directoryOK )
+ {
+ cerr << "highlight: Could not access directory "
+ << searchDir
+ << ", aborted.\n";
+ return false;
+ }
+
+ sort ( filePaths.begin(), filePaths.end() );
+ string suffix, desc;
+ cout << "\nInstalled language definitions"
+ << " (located in " << directory << "):\n\n";
+
+ for ( unsigned int i=0;i< filePaths.size(); i++ )
+ {
+ ConfigurationReader lang ( filePaths[i] );
+ desc = lang.getParameter ( "description" );
+ suffix = ( filePaths[i] ).substr ( directory.length() ) ;
+ suffix = suffix.substr ( 1, suffix.length()- wildcard.length() );
+ cout << setw ( 20 ) <<setiosflags ( ios::left ) <<desc<<": "<<suffix;
+ int extCnt=0;
+ for (StringMap::iterator it=extensions.begin();it!=extensions.end();it++) {
+ if (it->second==suffix ) {
+
+ cout << ((++extCnt==1)?" ( ":" ")<<it->first;
+ }
+ }
+ cout << ((extCnt)?" )":"")<<endl;
+ }
+ cout <<"\nUse name of the desired language"
+ << " with the --" OPT_SYNTAX " option.\n" << endl;
+ return true;
+}
+
+void HLCmdLineApp::printDebugInfo ( const highlight::LanguageDefinition &lang,
+ const string & langDefPath )
+{
+ cerr << "\nLoading language definition:\n" << langDefPath;
+ cerr << "\n\nDescription: " << lang.getDescription();
+ cerr << "\n\nSYMBOLS (followed by states):\n" << lang.getSymbolString();
+ cerr << "\n\nREGEX:\n";
+ highlight::RegexElement *re=NULL;
+ for ( unsigned int i=0; i<lang.getRegexElements().size(); i++ )
+ {
+ re = lang.getRegexElements() [i];
+ cerr << "State "<<re->open<<":\t"<<re->rePattern->getPattern() <<"\n";
+ }
+ cerr << "\nKEYWORDS:\n";
+ highlight::KeywordMap::iterator it;
+ highlight::KeywordMap keys=lang.getKeywords();
+ for ( it=keys.begin(); it!=keys.end(); it++ )
+ {
+ cerr << " "<< it->first << "("<< it->second << ")";
+ }
+ cerr <<"\n\n";
+}
+
+void HLCmdLineApp::printConfigInfo ( const string& configFile )
+{
+ cout << "\nRoot paths (modify with --" OPT_DATADIR " and --" OPT_ADDDATADIR "):\n";
+ cout << " Data directory: "<<dataDir.getDir() <<"\n";
+ if ( !dataDir.getAdditionalDataDir().empty() )
+ cout << " User defined directory: "<<dataDir.getAdditionalDataDir() <<"\n";
+ cout << "\nDefault search paths:\n";
+ cout << " Language definitions: "<<dataDir.getLangPath ( "", true ) <<"\n";
+ cout << " Colour themes: "<<dataDir.getThemePath ( "", true ) <<"\n";
+
+ if ( !dataDir.getAdditionalDataDir().empty() )
+ {
+ cout << "\nAdditional search paths:\n";
+ cout << " Language definitions: "<<dataDir.getAdditionalLangDefDir() <<"\n";
+ cout << " Colour themes: "<<dataDir.getAdditionalThemeDir() <<"\n";
+// cout << " Indentation schemes: "<<dataDir.getAdditionalIndentSchemesDir()<<"\n";
+ }
+
+ cout << "\nConfiguration paths:\n";
+ cout << " Configuration files: "<<dataDir.getConfDir ( true ) <<"\n";
+ cout << " User configuration: "<<configFile<<"\n";
+ if ( !dataDir.getAdditionalConfDir().empty() )
+ {
+ cout << "\nAdditional search paths:\n";
+ cout << " Configuration files: "<<dataDir.getAdditionalConfDir() <<"\n";
+ }
+ cout << endl;
+#ifdef HL_DATA_DIR
+ cout << "Compiler directive HL_DATA_DIR = " <<HL_DATA_DIR<< "\n";
+#endif
+#ifdef HL_CONFIG_DIR
+ cout << "Compiler directive HL_CONFIG_DIR = " <<HL_CONFIG_DIR<< "\n";
+#endif
+
+ cout << endl;
+}
+
+string HLCmdLineApp::getFileSuffix ( const string &fileName )
+{
+ size_t ptPos=fileName.rfind ( "." );
+ return ( ptPos == string::npos ) ? "" : fileName.substr ( ptPos+1, fileName.length() );
+}
+
+bool HLCmdLineApp::loadFileTypeConfig ( const string& name, StringMap* extMap, StringMap* shebangMap )
+{
+ if ( !extMap || !shebangMap ) return false;
+ string confPath=dataDir.getConfDir() + name + ".conf";
+ ConfigurationReader config ( confPath );
+ if ( config.found() )
+ {
+ stringstream values;
+ string paramName, paramVal;
+ for ( unsigned int i=0;i<config.getParameterNames().size();i++ )
+ {
+ paramName = config.getParameterNames() [i];
+
+ if ( paramName.find ( "ext" ) != string::npos )
+ {
+ values.str ( StringTools::change_case ( config.getParameter ( paramName ) ) );
+ paramName = StringTools::getParantheseVal ( paramName );
+ while ( values >> paramVal )
+ {
+ extMap->insert ( make_pair ( paramVal, paramName ) );
+ }
+ values.clear();
+ }
+ else if ( paramName.find ( "shebang" ) != string::npos )
+ {
+ values.str ( config.getParameter ( paramName ) ) ;
+ paramName = StringTools::getParantheseVal ( paramName );
+ while ( values >> paramVal )
+ {
+ shebangMap->insert ( make_pair ( paramVal, paramName ) );
+ }
+ values.clear();
+ }
+ }
+ return true;
+ }
+ else
+ {
+ cerr << "highlight: Configuration file "<< confPath << " not found.\n";
+ return false;
+ }
+}
+
+
+int HLCmdLineApp::getNumDigits ( int i )
+{
+ int res=0;
+ while ( i )
+ {
+ i/=10;
+ ++res;
+ }
+ return res;
+}
+
+void HLCmdLineApp::printProgressBar ( int total, int count )
+{
+ if ( !total ) return;
+ int p=100*count / total;
+ int numProgressItems=p/10;
+ cout << "\r[";
+ for ( int i=0;i<10;i++ )
+ {
+ cout << ( ( i<numProgressItems ) ?"#":" " );
+ }
+ cout<< "] " <<setw ( 3 ) <<p<<"%, "<<count << " / " << total << " " <<flush;
+ if ( p==100 )
+ {
+ cout << endl;
+ }
+}
+
+void HLCmdLineApp::printCurrentAction ( const string&outfilePath,
+ int total, int count, int countWidth )
+{
+ cout << "Writing file "
+ << setw ( countWidth ) << count
+ << " of "
+ << total
+ << ": "
+ << outfilePath
+ << "\n";
+}
+
+void HLCmdLineApp::printIOErrorReport ( unsigned int numberErrorFiles,
+ vector<string> & fileList,
+ const string &action )
+{
+ cerr << "highlight: Could not "
+ << action
+ << " file"
+ << ( ( numberErrorFiles>1 ) ?"s":"" ) <<":\n";
+ copy ( fileList.begin(), fileList.end(), ostream_iterator<string> ( cerr, "\n" ) );
+ if ( fileList.size() < numberErrorFiles )
+ {
+ cerr << "... ["
+ << ( numberErrorFiles - fileList.size() )
+ << " of "
+ << numberErrorFiles
+ << " failures not shown, use --"
+ << OPT_VERBOSE
+ << " switch to print all failures]\n";
+ }
+}
+
+string HLCmdLineApp::analyzeFile ( const string& file )
+{
+ string firstLine;
+
+ if ( !file.empty() )
+ {
+ ifstream inFile ( file.c_str() );
+ getline ( inFile, firstLine );
+ }
+ else
+ {
+ // This copies all the data to a new buffer, uses the data to get the
+ // first line, then makes cin use the new buffer that underlies the
+ // stringstream instance
+ cin_bufcopy << cin.rdbuf();
+ getline ( cin_bufcopy, firstLine );
+ cin_bufcopy.seekg ( 0, ios::beg );
+ cin.rdbuf ( cin_bufcopy.rdbuf() );
+ }
+ StringMap::iterator it;
+ for ( it=scriptShebangs.begin(); it!=scriptShebangs.end();it++ )
+ {
+ if ( Pattern::matches ( it->first, firstLine ) ) return it->second;
+ }
+ return "";
+}
+
+string HLCmdLineApp::guessFileType ( const string& suffix, const string &inputFile )
+{
+ string lcSuffix = StringTools::change_case ( suffix );
+ string fileType = ( extensions.count ( lcSuffix ) ) ? extensions[lcSuffix] : lcSuffix ;
+ if ( !fileType.empty() ) return fileType;
+ return analyzeFile ( inputFile );
+}
+
+
+int HLCmdLineApp::run ( const int argc, const char*argv[] )
+{
+
+ CmdLineOptions options ( argc, argv );
+
+ // set data directory path, where /langDefs and /themes reside
+ string dataDirPath = ( options.getDataDir().empty() ) ? Platform::getAppPath() :options.getDataDir();
+
+ if ( options.printVersion() )
+ {
+ printVersionInfo();
+ return EXIT_SUCCESS;
+ }
+
+
+
+
+ dataDir.setAdditionalDataDir ( options.getAdditionalDataDir() );
+ dataDir.setAdditionalConfDir ( options.getAdditionalConfDir() );
+
+ if ( ! dataDir.searchDataDir ( dataDirPath ) )
+ {
+ printBadInstallationInfo();
+ return EXIT_FAILURE;
+ }
+
+ if ( options.printHelp() )
+ {
+ Help::printHelp();
+ return EXIT_SUCCESS;
+ }
+
+ if ( options.printConfigInfo() )
+ {
+ printConfigInfo ( options.getConfigFilePath() );
+ return EXIT_SUCCESS;
+ }
+
+ if ( options.showThemes() )
+ {
+ return printInstalledThemes() ?EXIT_SUCCESS:EXIT_FAILURE;
+ }
+
+ //call before printInstalledLanguages!
+ loadFileTypeConfig ( "filetypes", &extensions, &scriptShebangs );
+
+ if ( options.showLangdefs() )
+ {
+ return printInstalledLanguages() ?EXIT_SUCCESS:EXIT_FAILURE;
+ }
+
+ const vector <string> inFileList=options.getInputFileNames();
+
+ if ( options.enableBatchMode() && inFileList[0].empty() )
+ {
+ return EXIT_FAILURE;
+ }
+
+ string themePath=dataDir.getThemePath ( options.getThemeName() );
+
+ auto_ptr<highlight::CodeGenerator> generator ( highlight::CodeGenerator::getInstance ( options.getOutputType() ) );
+
+
+ generator->setHTMLAttachAnchors ( options.attachLineAnchors() );
+ generator->setHTMLOrderedList ( options.orderedList() );
+ generator->setHTMLInlineCSS ( options.inlineCSS() );
+ generator->setHTMLEnclosePreTag ( options.enclosePreTag() );
+ generator->setHTMLAnchorPrefix ( options.getAnchorPrefix() );
+ generator->setHTMLClassName ( options.getClassName() );
+
+ generator->setLATEXReplaceQuotes ( options.replaceQuotes() );
+ generator->setLATEXNoShorthands ( options.disableBabelShorthands() );
+ generator->setLATEXPrettySymbols ( options.prettySymbols() );
+
+ generator->setRTFPageSize ( options.getPageSize() );
+ generator->setRTFCharStyles ( options.includeCharStyles() );
+
+ generator->setSVGSize ( options.getSVGWidth(), options.getSVGHeight() );
+
+ if (options.useCRDelimiter())
+ generator->setEOLDelimiter('\r');
+
+ generator->setValidateInput ( options.validateInput() );
+ generator->setStyleInputPath ( options.getStyleInFilename() );
+ generator->setStyleOutputPath ( options.getStyleOutFilename() );
+ generator->setIncludeStyle ( options.includeStyleDef() );
+ generator->setPrintLineNumbers ( options.printLineNumbers(), options.getNumberStart() );
+ generator->setPrintZeroes ( options.fillLineNrZeroes() );
+ generator->setFragmentCode ( options.fragmentOutput() );
+ generator->setPreformatting ( options.getWrappingStyle(),
+ ( generator->getPrintLineNumbers() ) ?
+ options.getLineLength() - options.getNumberWidth() : options.getLineLength(),
+ options.getNumberSpaces() );
+
+ generator->setEncoding ( options.getEncoding() );
+ generator->setBaseFont ( options.getBaseFont() ) ;
+ generator->setBaseFontSize ( options.getBaseFontSize() ) ;
+ generator->setLineNumberWidth ( options.getNumberWidth() );
+ generator->setStartingNestedLang( options.getStartNestedLang());
+ generator->disableTrailingNL(options.disableTrailingNL());
+
+ bool styleFileWanted = !options.fragmentOutput() || options.styleOutPathDefined();
+
+ if ( !generator->initTheme ( themePath ) )
+ {
+ cerr << "highlight: Could not find style "
+ << themePath
+ << ".\n";
+ return EXIT_FAILURE;
+ }
+
+ if ( options.printOnlyStyle() )
+ {
+ if (!options.formatSupportsExtStyle()){
+ cerr << "highlight: output format supports no external styles.\n";
+ return EXIT_FAILURE;
+ }
+ bool useStdout = options.getStyleOutFilename() =="stdout";
+ string cssOutFile=options.getOutDirectory() + options.getStyleOutFilename();
+ bool success=generator->printExternalStyle ( useStdout?"":cssOutFile );
+ if ( !success )
+ {
+ cerr << "highlight: Could not write " << cssOutFile <<".\n";
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+ }
+
+ bool formattingEnabled = generator->initIndentationScheme ( options.getIndentScheme() );
+
+ if ( !formattingEnabled && !options.getIndentScheme().empty() )
+ {
+ cerr << "highlight: Undefined indentation scheme "
+ << options.getIndentScheme()
+ << ".\n";
+ return EXIT_FAILURE;
+ }
+
+ if ( !options.getTagsFile().empty() )
+ {
+ if ( !generator->initTagInformation ( options.getTagsFile() ) )
+ {
+ cerr << "highlight: Could not load ctags file "
+ << options.getTagsFile()
+ << ".\n";
+ return EXIT_FAILURE;
+ }
+ }
+
+ string outDirectory = options.getOutDirectory();
+#ifndef WIN32
+ ifstream dirTest ( outDirectory.c_str() );
+ if ( !outDirectory.empty() && !options.quietMode() && !dirTest )
+ {
+ cerr << "highlight: Output directory \""
+ << outDirectory
+ << "\" does not exist.\n";
+ return EXIT_FAILURE;
+ }
+ dirTest.close();
+#endif
+
+ map <int,string> markedLines = options.getMarkLines();
+ if ( !markedLines.empty() )
+ {
+ map<int, string>::iterator it;
+ for ( it=markedLines.begin(); it!=markedLines.end();it++ )
+ {
+ generator->addMarkedLine ( it->first, it->second );
+ }
+ }
+
+ bool initError=false, IOError=false;
+ unsigned int fileCount=inFileList.size(),
+ fileCountWidth=getNumDigits ( fileCount ),
+ i=0,
+ numBadFormatting=0,
+ numBadInput=0,
+ numBadOutput=0;
+
+ vector<string> badFormattedFiles, badInputFiles, badOutputFiles;
+ string inFileName, outFilePath;
+ string suffix, lastSuffix;
+
+ if ( options.syntaxGiven() ) // user defined language definition, valid for all files
+ {
+ suffix = guessFileType ( options.getLanguage() );
+ }
+
+ while ( i < fileCount && !initError )
+ {
+ if ( !options.syntaxGiven() ) // determine file type for each file
+ {
+ suffix = guessFileType ( getFileSuffix ( inFileList[i] ), inFileList[i] );
+ }
+ if ( suffix.empty() )
+ {
+ if ( !options.enableBatchMode() )
+ cerr << "highlight: Undefined language definition. Use --"
+ << OPT_SYNTAX << " option.\n";
+ if ( !options.forceOutput() )
+ {
+ initError = true;
+ break;
+ }
+ }
+
+ if ( suffix != lastSuffix )
+ {
+ string langDefPath=dataDir.getLangPath ( suffix+".lang" );
+ highlight::LoadResult loadRes= generator->loadLanguage ( langDefPath );
+ if ( loadRes==highlight::LOAD_FAILED_REGEX )
+ {
+ cerr << "highlight: Regex error ( "
+ << generator->getLanguage().getFailedRegex()
+ << " ) in "<<suffix<<".lang\n";
+ initError = true;
+ break;
+ }
+ else if ( loadRes==highlight::LOAD_FAILED )
+ {
+ // do also ignore error msg if --syntax parameter should be skipped
+ if ( ! (options.quietMode() || options.isSkippedExt ( suffix )) )
+ {
+ cerr << "highlight: Unknown source file extension \""
+ << suffix
+ << "\".\n";
+ }
+ if ( !options.forceOutput() )
+ {
+ initError = true;
+ break;
+ }
+ }
+ if ( options.printDebugInfo() && loadRes==highlight::LOAD_NEW )
+ {
+ printDebugInfo ( generator->getLanguage(), langDefPath );
+ }
+ lastSuffix = suffix;
+ }
+
+ string::size_type pos= ( inFileList[i] ).find_last_of ( Platform::pathSeparator );
+ inFileName = inFileList[i].substr ( pos+1 );
+
+ if ( options.enableBatchMode() )
+ {
+ outFilePath = outDirectory;
+ outFilePath += inFileName;
+ outFilePath += options.getOutFileSuffix();
+
+ if ( !options.quietMode() )
+ {
+ if ( options.printProgress() )
+ {
+ printProgressBar ( fileCount, i+1 );
+ }
+ else
+ {
+ printCurrentAction ( outFilePath, fileCount, i+1, fileCountWidth );
+ }
+ }
+ }
+ else
+ {
+ outFilePath = options.getSingleOutFilename();
+ if ( outFilePath.size() && outFilePath==options.getSingleInFilename() )
+ {
+ cerr << "highlight: Output path equals input path: \""
+ << outFilePath << "\".\n";
+ initError = true;
+ break;
+ }
+
+ }
+
+ if ( options.useFNamesAsAnchors() )
+ {
+ generator->setHTMLAnchorPrefix ( inFileName );
+ }
+
+ generator->setTitle ( options.getDocumentTitle().empty() ?
+ inFileList[i]:options.getDocumentTitle() );
+
+ generator->setKeyWordCase ( options.getKeywordCase() );
+
+ highlight::ParseError error = generator->generateFile ( inFileList[i], outFilePath );
+
+ if ( error==highlight::BAD_INPUT )
+ {
+ if ( numBadInput++ < IO_ERROR_REPORT_LENGTH || options.printDebugInfo() )
+ {
+ badInputFiles.push_back ( inFileList[i] );
+ }
+ }
+ else if ( error==highlight::BAD_OUTPUT )
+ {
+ if ( numBadOutput++ < IO_ERROR_REPORT_LENGTH || options.printDebugInfo() )
+ {
+ badOutputFiles.push_back ( outFilePath );
+ }
+ }
+ if ( formattingEnabled && !generator->formattingIsPossible() )
+ {
+ if ( numBadFormatting++ < IO_ERROR_REPORT_LENGTH || options.printDebugInfo() )
+ {
+ badFormattedFiles.push_back ( outFilePath );
+ }
+ }
+ ++i;
+ }
+
+
+ if ( i && !options.includeStyleDef()
+ && styleFileWanted
+ && options.formatSupportsExtStyle() )
+ {
+ string cssOutFile=outDirectory + options.getStyleOutFilename();
+ bool success=generator->printExternalStyle ( cssOutFile );
+ if ( !success )
+ {
+ cerr << "highlight: Could not write " << cssOutFile <<".\n";
+ IOError = true;
+ }
+ }
+
+ if ( i && options.printIndexFile() )
+ {
+ bool success=generator -> printIndexFile ( inFileList, outDirectory );
+ if ( !success )
+ {
+ cerr << "highlight: Could not write index file.\n";
+ IOError = true;
+ }
+ }
+
+ if ( numBadInput )
+ {
+ printIOErrorReport ( numBadInput, badInputFiles, "read input" );
+ IOError = true;
+ }
+ if ( numBadOutput )
+ {
+ printIOErrorReport ( numBadOutput, badOutputFiles, "write output" );
+ IOError = true;
+ }
+ if ( numBadFormatting )
+ {
+ printIOErrorReport ( numBadFormatting, badFormattedFiles, "reformat" );
+ }
+ return ( initError || IOError ) ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+int main ( const int argc, const char *argv[] )
+{
+ HLCmdLineApp app;
+ return app.run ( argc, argv );
+}
diff --git a/support/highlight/src/cli/main.h b/support/highlight/src/cli/main.h
new file mode 100644
index 0000000000..2839e5c9fd
--- /dev/null
+++ b/support/highlight/src/cli/main.h
@@ -0,0 +1,117 @@
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef HIGHLIGHT_APP
+#define HIGHLIGHT_APP
+
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <map>
+#include <iomanip>
+#include <cassert>
+
+//#include "./dirstream0.4/dirstream.h"
+#include "cmdlineoptions.h"
+#include "configurationreader.h"
+#include "codegenerator.h"
+#include "help.h"
+#include "datadir.h"
+#include "version.h"
+#include "platform_fs.h"
+
+#define IO_ERROR_REPORT_LENGTH 5
+#define SHEBANG_CNT 12
+
+typedef map<string, string> StringMap;
+
+/// Main application class of the command line interface
+
+class HLCmdLineApp
+{
+
+ public:
+
+ HLCmdLineApp() {};
+ ~HLCmdLineApp() {};
+
+ /** Start application
+ \param argc Number of command line arguments
+ \param argv values of command line arguments
+ \return EXIT_SUCCESS or EXIT_FAILURE
+ */
+ int run ( const int argc, const char *argv[] );
+
+ private:
+
+ DataDir dataDir;
+ StringMap extensions;
+ StringMap scriptShebangs;
+ stringstream cin_bufcopy;
+
+ /** print version info*/
+ void printVersionInfo();
+
+ /** print configuration info*/
+ void printConfigInfo ( const string& );
+
+ /** print error message*/
+ void printBadInstallationInfo();
+
+ /** print input and output errors */
+ void printIOErrorReport ( unsigned int numberErrorFiles, vector<string> & fileList, const string &action );
+
+ /** list installed theme files
+ \return true if theme files were found
+ */
+ bool printInstalledThemes();
+
+ /** list installed language definition files
+ \return true if lang files were found
+ */
+ bool printInstalledLanguages();
+
+ /** print debug information
+ \param lang language definition
+ \param langDefPath path to language definition
+ */
+ void printDebugInfo ( const highlight::LanguageDefinition &lang,
+ const string &langDefPath );
+
+ string getFileSuffix ( const string &fileName );
+
+ string guessFileType ( const string &suffix, const string &inputFile="" );
+
+ int getNumDigits ( int i );
+
+ void printProgressBar ( int total, int count );
+ void printCurrentAction ( const string&outfilePath,
+ int total, int count, int countWidth );
+
+ bool readInputFilePaths ( vector<string> &fileList, string wildcard,
+ bool recursiveSearch );
+
+ string analyzeFile ( const string& file );
+ bool loadFileTypeConfig ( const string& name, StringMap* map, StringMap* shebangMap );
+
+};
+
+#endif
diff --git a/support/highlight/src/core/ansigenerator.cpp b/support/highlight/src/core/ansigenerator.cpp
new file mode 100644
index 0000000000..5c3133619a
--- /dev/null
+++ b/support/highlight/src/core/ansigenerator.cpp
@@ -0,0 +1,109 @@
+/***************************************************************************
+ ansigenerator.cpp - description
+ -------------------
+ begin : Jul 5 2004
+ copyright : (C) 2004-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <sstream>
+
+#include "ansigenerator.h"
+
+using namespace std;
+
+namespace highlight
+{
+
+ string AnsiGenerator::getOpenTag ( const string&font,
+ const string&fgCol, const string&bgCol )
+ {
+ ostringstream s;
+ s << "\033["<<font;
+ if ( !fgCol.empty() )
+ s<<";"<<fgCol;
+ if ( !bgCol.empty() )
+ s<<";"<<bgCol;
+ s << "m";
+ return s.str();
+ }
+
+
+ AnsiGenerator::AnsiGenerator() : CodeGenerator ( ANSI )
+ {
+
+ newLineTag = "\n";
+ spacer = " ";
+ }
+
+ AnsiGenerator::~AnsiGenerator() {}
+
+ void AnsiGenerator::initOutputTags(){
+ openTags.push_back ( "" );
+ openTags.push_back ( getOpenTag ( "00", "31" ) ); //str
+ openTags.push_back ( getOpenTag ( "00", "34" ) );//number
+ openTags.push_back ( getOpenTag ( "00", "34" ) );//sl comment
+ openTags.push_back ( getOpenTag ( "00", "34" ) );//ml comment
+ openTags.push_back ( getOpenTag ( "00", "35" ) );//escapeChar
+ openTags.push_back ( getOpenTag ( "00", "35" ) );//directive
+ openTags.push_back ( getOpenTag ( "00", "31" ) );//directive string
+ openTags.push_back ( getOpenTag ( "00", "30" ) );//linenum
+ openTags.push_back ( getOpenTag ( "00", "00" ) );//symbol
+
+ closeTags.push_back ( "" );
+ for ( int i=1;i<NUMBER_BUILTIN_STATES; i++ )
+ {
+ closeTags.push_back ( "\033[m" );
+ }
+ }
+
+ string AnsiGenerator::getHeader()
+ {
+ return string();
+ }
+
+ void AnsiGenerator::printBody()
+ {
+ processRootState();
+ }
+
+ string AnsiGenerator::getFooter()
+ {
+ return string();
+ }
+
+ string AnsiGenerator::maskCharacter ( unsigned char c )
+ {
+ return string ( 1, c );
+ }
+
+ string AnsiGenerator::getKeywordOpenTag ( unsigned int styleID )
+ {
+ return ( styleID ) ?getOpenTag ( "00", "32", "" ) :getOpenTag ( "00", "33" );
+ }
+
+ string AnsiGenerator::getKeywordCloseTag ( unsigned int styleID )
+ {
+ return "\033[m";
+ }
+
+}
diff --git a/support/highlight/src/core/ansigenerator.h b/support/highlight/src/core/ansigenerator.h
new file mode 100644
index 0000000000..51ac965a5c
--- /dev/null
+++ b/support/highlight/src/core/ansigenerator.h
@@ -0,0 +1,89 @@
+/***************************************************************************
+ ansicode.h - description
+ -------------------
+ begin : Jul 5 2004
+ copyright : (C) 2004-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef ANSIGENERATOR_H
+#define ANSIGENERATOR_H
+
+#include <string>
+
+#include "codegenerator.h"
+#include "charcodes.h"
+#include "version.h"
+
+namespace highlight
+{
+
+ /**
+ \brief This class generates ANSI escape sequences.
+
+ It contains information about the resulting document structure (document
+ header and footer), the colour system, white space handling and text
+ formatting attributes.
+
+ * @author Andre Simon
+ */
+
+ class AnsiGenerator : public highlight::CodeGenerator
+ {
+ public:
+ AnsiGenerator();
+ ~AnsiGenerator();
+
+ /** prints document header
+ */
+ string getHeader();
+
+ /** Prints document footer*/
+ string getFooter();
+
+ /** Prints document body*/
+ void printBody();
+
+ private:
+
+ /** \return escaped character*/
+ virtual string maskCharacter ( unsigned char );
+
+
+ /** gibt ANSI-"Tags" zurueck (Farbindex+bold+kursiv)*/
+ string getOpenTag ( const string&font,
+ const string&fgCol, const string&bgCol="" );
+
+ /** initialize tags in specific format according to colouring information provided in DucumentStyle */
+ void initOutputTags();
+
+ /** @param styleID current style ID
+ @return matching sequence to begin a new element formatting*/
+ string getKeywordOpenTag ( unsigned int styleID );
+
+ /** @param styleID current style ID
+ @return matching sequence to stop element formatting*/
+ string getKeywordCloseTag ( unsigned int styleID );
+ };
+
+}
+#endif
diff --git a/support/highlight/src/core/astyle/ASBeautifier.cpp b/support/highlight/src/core/astyle/ASBeautifier.cpp
new file mode 100644
index 0000000000..899d46d16b
--- /dev/null
+++ b/support/highlight/src/core/astyle/ASBeautifier.cpp
@@ -0,0 +1,2658 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Copyright (C) 2006-2010 by Jim Pattee <jimp03@email.com>
+ * Copyright (C) 1998-2002 by Tal Davidson
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>
+ *
+ * This file is a part of Artistic Style - an indentation and
+ * reformatting tool for C, C++, C# and Java source files.
+ * <http://astyle.sourceforge.net>
+ *
+ * Artistic Style is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Artistic Style is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Artistic Style. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+#include "astyle.h"
+
+#include <algorithm>
+#include <iostream>
+
+
+namespace astyle
+{
+// static member variables
+int ASBeautifier::beautifierFileType = 9; // initialized with an invalid type
+vector<const string*>* ASBeautifier::headers = NULL;
+vector<const string*>* ASBeautifier::nonParenHeaders = NULL;
+vector<const string*>* ASBeautifier::preBlockStatements;
+vector<const string*>* ASBeautifier::assignmentOperators = NULL;
+vector<const string*>* ASBeautifier::nonAssignmentOperators;
+vector<const string*>* ASBeautifier::indentableHeaders;
+
+
+/**
+ * ASBeautifier's constructor
+ */
+ASBeautifier::ASBeautifier()
+{
+ waitingBeautifierStack = NULL;
+ activeBeautifierStack = NULL;
+ waitingBeautifierStackLengthStack = NULL;
+ activeBeautifierStackLengthStack = NULL;
+
+ headerStack = NULL;
+ tempStacks = NULL;
+ blockParenDepthStack = NULL;
+ blockStatementStack = NULL;
+ parenStatementStack = NULL;
+ bracketBlockStateStack = NULL;
+ inStatementIndentStack = NULL;
+ inStatementIndentStackSizeStack = NULL;
+ parenIndentStack = NULL;
+ sourceIterator = NULL;
+ isIndentManuallySet = false;
+ isMinConditionalManuallySet = false;
+ isModeManuallySet = false;
+ shouldForceTabIndentation = false;
+ setSpaceIndentation(4); // also sets minConditionalIndent
+ setMaxInStatementIndentLength(40);
+ classInitializerTabs = 1;
+ setClassIndent(false);
+ setSwitchIndent(false);
+ setCaseIndent(false);
+ setBlockIndent(false);
+ setBracketIndent(false);
+ setNamespaceIndent(false);
+ setLabelIndent(false);
+ setEmptyLineFill(false);
+ setCStyle();
+ setPreprocessorIndent(false);
+
+ // initialize ASBeautifier static member vectors
+ beautifierFileType = 9; // reset to an invalid type
+ initVector(headers);
+ initVector(nonParenHeaders);
+ initVector(assignmentOperators);
+ initVector(nonAssignmentOperators);
+ initVector(preBlockStatements);
+ initVector(indentableHeaders);
+}
+
+/**
+ * ASBeautifier's copy constructor
+ * must explicitly call the base class copy constructor
+ */
+ASBeautifier::ASBeautifier(const ASBeautifier &other) : ASBase(other)
+{
+ // these don't need to copy the stack
+ waitingBeautifierStack = NULL;
+ activeBeautifierStack = NULL;
+ waitingBeautifierStackLengthStack = NULL;
+ activeBeautifierStackLengthStack = NULL;
+
+ // vector '=' operator performs a DEEP copy of all elements in the vector
+
+ headerStack = new vector<const string*>;
+ *headerStack = *other.headerStack;
+
+ //tempStacks = new vector<vector<const string*>*>;
+ //vector<vector<const string*>*>::iterator iter;
+ //for (iter = other.tempStacks->begin();
+ // iter != other.tempStacks->end();
+ // ++iter)
+ //{
+ // vector<const string*> *newVec = new vector<const string*>;
+ // *newVec = **iter;
+ // tempStacks->push_back(newVec);
+ //}
+ tempStacks = copyTempStacks(other);
+
+ blockParenDepthStack = new vector<int>;
+ *blockParenDepthStack = *other.blockParenDepthStack;
+
+ blockStatementStack = new vector<bool>;
+ *blockStatementStack = *other.blockStatementStack;
+
+ parenStatementStack = new vector<bool>;
+ *parenStatementStack = *other.parenStatementStack;
+
+ bracketBlockStateStack = new vector<bool>;
+ *bracketBlockStateStack = *other.bracketBlockStateStack;
+
+ inStatementIndentStack = new vector<int>;
+ *inStatementIndentStack = *other.inStatementIndentStack;
+
+ inStatementIndentStackSizeStack = new vector<int>;
+ *inStatementIndentStackSizeStack = *other.inStatementIndentStackSizeStack;
+
+ parenIndentStack = new vector<int>;
+ *parenIndentStack = *other.parenIndentStack;
+
+ sourceIterator = other.sourceIterator;
+
+ // protected variables
+ // variables set by ASFormatter
+ // must also be updated in activeBeautifierStack
+ inLineNumber = other.inLineNumber;
+ horstmannIndentInStatement = other.horstmannIndentInStatement;
+ nonInStatementBracket = other.nonInStatementBracket;
+ lineCommentNoBeautify = other.lineCommentNoBeautify;
+ isNonInStatementArray = other.isNonInStatementArray;
+ isSharpAccessor = other.isSharpAccessor;
+ isSharpDelegate = other.isSharpDelegate;
+ isInExtern = other.isInExtern;
+ isInBeautifySQL = other.isInBeautifySQL;
+ isInIndentableStruct = other.isInIndentableStruct;
+
+ // private variables
+ indentString = other.indentString;
+ currentHeader = other.currentHeader;
+ previousLastLineHeader = other.previousLastLineHeader;
+ probationHeader = other.probationHeader;
+ isInQuote = other.isInQuote;
+ isInVerbatimQuote = other.isInVerbatimQuote;
+ haveLineContinuationChar = other.haveLineContinuationChar;
+ isInAsm = other.isInAsm;
+ isInAsmOneLine = other.isInAsmOneLine;
+ isInAsmBlock = other.isInAsmBlock;
+ isInComment = other.isInComment;
+ isInHorstmannComment = other.isInHorstmannComment;
+ isInCase = other.isInCase;
+ isInQuestion = other.isInQuestion;
+ isInStatement = other.isInStatement;
+ isInHeader = other.isInHeader;
+ isInTemplate = other.isInTemplate;
+ isInDefine = other.isInDefine;
+ isInDefineDefinition = other.isInDefineDefinition;
+ classIndent = other.classIndent;
+ isInClassInitializer = other.isInClassInitializer;
+ isInClassHeaderTab = other.isInClassHeaderTab;
+ isInEnum = other.isInEnum;
+ switchIndent = other.switchIndent;
+ caseIndent = other.caseIndent;
+ namespaceIndent = other.namespaceIndent;
+ bracketIndent = other.bracketIndent;
+ blockIndent = other.blockIndent;
+ labelIndent = other.labelIndent;
+ preprocessorIndent = other.preprocessorIndent;
+ isInConditional = other.isInConditional;
+ isIndentManuallySet = other.isIndentManuallySet;
+ isMinConditionalManuallySet = other.isMinConditionalManuallySet;
+ isModeManuallySet = other.isModeManuallySet;
+ shouldForceTabIndentation = other.shouldForceTabIndentation;
+ emptyLineFill = other.emptyLineFill;
+ lineOpensComment = other.lineOpensComment;
+ backslashEndsPrevLine = other.backslashEndsPrevLine;
+ blockCommentNoIndent = other.blockCommentNoIndent;
+ blockCommentNoBeautify = other.blockCommentNoBeautify;
+ previousLineProbationTab = other.previousLineProbationTab;
+ fileType = other.fileType;
+ minConditionalIndent = other.minConditionalIndent;
+ parenDepth = other.parenDepth;
+ indentLength = other.indentLength;
+ blockTabCount = other.blockTabCount;
+ maxInStatementIndent = other.maxInStatementIndent;
+ classInitializerTabs = other.classInitializerTabs;
+ templateDepth = other.templateDepth;
+ prevFinalLineSpaceTabCount = other.prevFinalLineSpaceTabCount;
+ prevFinalLineTabCount = other.prevFinalLineTabCount;
+ defineTabCount = other.defineTabCount;
+ quoteChar = other.quoteChar;
+ prevNonSpaceCh = other.prevNonSpaceCh;
+ currentNonSpaceCh = other.currentNonSpaceCh;
+ currentNonLegalCh = other.currentNonLegalCh;
+ prevNonLegalCh = other.prevNonLegalCh;
+}
+
+/**
+ * ASBeautifier's destructor
+ */
+ASBeautifier::~ASBeautifier()
+{
+ deleteContainer(waitingBeautifierStack);
+ deleteContainer(activeBeautifierStack);
+ deleteContainer(waitingBeautifierStackLengthStack);
+ deleteContainer(activeBeautifierStackLengthStack);
+ deleteContainer(headerStack);
+ deleteContainer(tempStacks);
+ deleteContainer(blockParenDepthStack);
+ deleteContainer(blockStatementStack);
+ deleteContainer(parenStatementStack);
+ deleteContainer(bracketBlockStateStack);
+ deleteContainer(inStatementIndentStack);
+ deleteContainer(inStatementIndentStackSizeStack);
+ deleteContainer(parenIndentStack);
+}
+
+/**
+ * initialize the ASBeautifier.
+ *
+ * init() should be called every time a ABeautifier object is to start
+ * beautifying a NEW source file.
+ * init() recieves a pointer to a ASSourceIterator object that will be
+ * used to iterate through the source code.
+ *
+ * @param iter a pointer to the ASSourceIterator or ASStreamIterator object.
+ */
+void ASBeautifier::init(ASSourceIterator *iter)
+{
+ sourceIterator = iter;
+ init();
+}
+
+/**
+ * initialize the ASBeautifier.
+ */
+void ASBeautifier::init()
+{
+ initStatic();
+ ASBase::init(getFileType());
+
+ initContainer(waitingBeautifierStack, new vector<ASBeautifier*>);
+ initContainer(activeBeautifierStack, new vector<ASBeautifier*>);
+
+ initContainer(waitingBeautifierStackLengthStack, new vector<int>);
+ initContainer(activeBeautifierStackLengthStack, new vector<int>);
+
+ initContainer(headerStack, new vector<const string*>);
+
+ initContainer(tempStacks, new vector<vector<const string*>*>);
+ tempStacks->push_back(new vector<const string*>);
+
+ initContainer(blockParenDepthStack, new vector<int>);
+ initContainer(blockStatementStack, new vector<bool>);
+ initContainer(parenStatementStack, new vector<bool>);
+
+ initContainer(bracketBlockStateStack, new vector<bool>);
+ bracketBlockStateStack->push_back(true);
+
+ initContainer(inStatementIndentStack, new vector<int>);
+ initContainer(inStatementIndentStackSizeStack, new vector<int>);
+ inStatementIndentStackSizeStack->push_back(0);
+ initContainer(parenIndentStack, new vector<int>);
+
+ previousLastLineHeader = NULL;
+ currentHeader = NULL;
+
+ isInQuote = false;
+ isInVerbatimQuote = false;
+ haveLineContinuationChar = false;
+ isInAsm = false;
+ isInAsmOneLine = false;
+ isInAsmBlock = false;
+ isInComment = false;
+ isInHorstmannComment = false;
+ isInStatement = false;
+ isInCase = false;
+ isInQuestion = false;
+ isInClassInitializer = false;
+ isInClassHeaderTab = false;
+ isInEnum = false;
+ isInHeader = false;
+ isInTemplate = false;
+ isInConditional = false;
+
+ templateDepth = 0;
+ parenDepth = 0;
+ blockTabCount = 0;
+ prevNonSpaceCh = '{';
+ currentNonSpaceCh = '{';
+ prevNonLegalCh = '{';
+ currentNonLegalCh = '{';
+ quoteChar = ' ';
+ prevFinalLineSpaceTabCount = 0;
+ prevFinalLineTabCount = 0;
+ probationHeader = NULL;
+ backslashEndsPrevLine = false;
+ lineOpensComment = false;
+ isInDefine = false;
+ isInDefineDefinition = false;
+ defineTabCount = 0;
+ lineCommentNoBeautify = false;
+ blockCommentNoIndent = false;
+ blockCommentNoBeautify = false;
+ previousLineProbationTab = false;
+ isNonInStatementArray = false;
+ isSharpAccessor = false;
+ isSharpDelegate = false;
+ isInExtern = false;
+ isInBeautifySQL = false;
+ isInIndentableStruct = false;
+ inLineNumber = 0;
+ horstmannIndentInStatement = 0;
+ nonInStatementBracket = 0;
+}
+
+/*
+ * initialize the static vars
+ */
+void ASBeautifier::initStatic()
+{
+ if (fileType == beautifierFileType) // don't build unless necessary
+ return;
+
+ beautifierFileType = fileType;
+
+ headers->clear();
+ nonParenHeaders->clear();
+ assignmentOperators->clear();
+ nonAssignmentOperators->clear();
+ preBlockStatements->clear();
+ indentableHeaders->clear();
+
+ ASResource::buildHeaders(headers, fileType, true);
+ ASResource::buildNonParenHeaders(nonParenHeaders, fileType, true);
+ ASResource::buildAssignmentOperators(assignmentOperators);
+ ASResource::buildNonAssignmentOperators(nonAssignmentOperators);
+ ASResource::buildPreBlockStatements(preBlockStatements, fileType);
+ ASResource::buildIndentableHeaders(indentableHeaders);
+}
+
+/**
+ * set indentation style to C/C++.
+ */
+void ASBeautifier::setCStyle()
+{
+ fileType = C_TYPE;
+}
+
+/**
+ * set indentation style to Java.
+ */
+void ASBeautifier::setJavaStyle()
+{
+ fileType = JAVA_TYPE;
+}
+
+/**
+ * set indentation style to C#.
+ */
+void ASBeautifier::setSharpStyle()
+{
+ fileType = SHARP_TYPE;
+}
+
+/**
+ * set mode manually set flag
+ */
+void ASBeautifier::setModeManuallySet(bool state)
+{
+ isModeManuallySet = state;
+}
+
+/**
+ * indent using one tab per indentation
+ */
+void ASBeautifier::setTabIndentation(int length, bool forceTabs)
+{
+ indentString = "\t";
+ indentLength = length;
+ shouldForceTabIndentation = forceTabs;
+
+ if (!isMinConditionalManuallySet)
+ minConditionalIndent = indentLength * 2;
+}
+
+/**
+ * indent using a number of spaces per indentation.
+ *
+ * @param length number of spaces per indent.
+ */
+void ASBeautifier::setSpaceIndentation(int length)
+{
+ indentString = string(length, ' ');
+ indentLength = length;
+
+ if (!isMinConditionalManuallySet)
+ minConditionalIndent = indentLength * 2;
+}
+
+/**
+ * set indent manually set flag
+ */
+void ASBeautifier::setIndentManuallySet(bool state)
+{
+ isIndentManuallySet = state;
+}
+
+/**
+ * set the maximum indentation between two lines in a multi-line statement.
+ *
+ * @param max maximum indentation length.
+ */
+void ASBeautifier::setMaxInStatementIndentLength(int max)
+{
+ maxInStatementIndent = max;
+}
+
+/**
+ * set the minimum indentation between two lines in a multi-line condition.
+ *
+ * @param min minimal indentation length.
+ */
+void ASBeautifier::setMinConditionalIndentLength(int min)
+{
+ minConditionalIndent = min;
+}
+
+/**
+ * set min conditional manually set flag
+ */
+void ASBeautifier::setMinConditionalManuallySet(bool state)
+{
+ isMinConditionalManuallySet = state;
+}
+
+/**
+ * set the state of the bracket indentation option. If true, brackets will
+ * be indented one additional indent.
+ *
+ * @param state state of option.
+ */
+void ASBeautifier::setBracketIndent(bool state)
+{
+ bracketIndent = state;
+}
+
+/**
+ * set the state of the block indentation option. If true, entire blocks
+ * will be indented one additional indent, similar to the GNU indent style.
+ *
+ * @param state state of option.
+ */
+void ASBeautifier::setBlockIndent(bool state)
+{
+ blockIndent = state;
+}
+
+/**
+ * set the state of the class indentation option. If true, C++ class
+ * definitions will be indented one additional indent.
+ *
+ * @param state state of option.
+ */
+void ASBeautifier::setClassIndent(bool state)
+{
+ classIndent = state;
+}
+
+/**
+ * set the state of the switch indentation option. If true, blocks of 'switch'
+ * statements will be indented one additional indent.
+ *
+ * @param state state of option.
+ */
+void ASBeautifier::setSwitchIndent(bool state)
+{
+ switchIndent = state;
+}
+
+/**
+ * set the state of the case indentation option. If true, lines of 'case'
+ * statements will be indented one additional indent.
+ *
+ * @param state state of option.
+ */
+void ASBeautifier::setCaseIndent(bool state)
+{
+ caseIndent = state;
+}
+
+/**
+ * set the state of the namespace indentation option.
+ * If true, blocks of 'namespace' statements will be indented one
+ * additional indent. Otherwise, NO indentation will be added.
+ *
+ * @param state state of option.
+ */
+void ASBeautifier::setNamespaceIndent(bool state)
+{
+ namespaceIndent = state;
+}
+
+/**
+ * set the state of the label indentation option.
+ * If true, labels will be indented one indent LESS than the
+ * current indentation level.
+ * If false, labels will be flushed to the left with NO
+ * indent at all.
+ *
+ * @param state state of option.
+ */
+void ASBeautifier::setLabelIndent(bool state)
+{
+ labelIndent = state;
+}
+
+/**
+ * set the state of the preprocessor indentation option.
+ * If true, multiline #define statements will be indented.
+ *
+ * @param state state of option.
+ */
+void ASBeautifier::setPreprocessorIndent(bool state)
+{
+ preprocessorIndent = state;
+}
+
+/**
+ * set the state of the empty line fill option.
+ * If true, empty lines will be filled with the whitespace.
+ * of their previous lines.
+ * If false, these lines will remain empty.
+ *
+ * @param state state of option.
+ */
+void ASBeautifier::setEmptyLineFill(bool state)
+{
+ emptyLineFill = state;
+}
+
+/**
+ * get the file type.
+ */
+int ASBeautifier::getFileType()
+{
+ return fileType;
+}
+
+/**
+ * get the number of spaces per indent
+ *
+ * @return value of indentLength option.
+ */
+int ASBeautifier::getIndentLength(void)
+{
+ return indentLength;
+}
+
+/**
+ * get the char used for indentation, space or tab
+ *
+ * @return the char used for indentation.
+ */
+string ASBeautifier::getIndentString(void)
+{
+ return indentString;
+}
+
+/**
+ * get indent manually set flag
+ */
+bool ASBeautifier::getIndentManuallySet()
+{
+ return isIndentManuallySet;
+}
+
+/**
+ * get the state of the isMinConditionalManuallySet flag
+ *
+ * @return the state of isMinConditionalManuallySet.
+ */
+bool ASBeautifier::getMinConditionalManuallySet()
+{
+ return isMinConditionalManuallySet;
+}
+
+/**
+ * get mode manually set flag
+ */
+bool ASBeautifier::getModeManuallySet()
+{
+ return isModeManuallySet;
+}
+
+/**
+ * get the state of the force tab indentation option.
+ *
+ * @return state of force tab indentation.
+ */
+bool ASBeautifier::getForceTabIndentation(void)
+{
+ return shouldForceTabIndentation;
+}
+
+/**
+ * get the state of the block indentation option.
+ *
+ * @return state of blockIndent option.
+ */
+bool ASBeautifier::getBlockIndent(void)
+{
+ return blockIndent;
+}
+
+/**
+ * get the state of the bracket indentation option.
+ *
+ * @return state of bracketIndent option.
+ */
+bool ASBeautifier::getBracketIndent(void)
+{
+ return bracketIndent;
+}
+
+/**
+ * get the state of the class indentation option. If true, blocks of
+ * the 'class' statement will be indented one additional indent.
+ *
+ * @return state of classIndent option.
+ */
+bool ASBeautifier::getClassIndent(void)
+{
+ return classIndent;
+}
+
+/**
+ * get the state of the switch indentation option. If true, blocks of
+ * the 'switch' statement will be indented one additional indent.
+ *
+ * @return state of switchIndent option.
+ */
+bool ASBeautifier::getSwitchIndent(void)
+{
+ return switchIndent;
+}
+
+/**
+ * get the state of the case indentation option. If true, lines of 'case'
+ * statements will be indented one additional indent.
+ *
+ * @return state of caseIndent option.
+ */
+bool ASBeautifier::getCaseIndent(void)
+{
+ return caseIndent;
+}
+
+/**
+ * get the state of the empty line fill option.
+ * If true, empty lines will be filled with the whitespace.
+ * of their previous lines.
+ * If false, these lines will remain empty.
+ *
+ * @return state of emptyLineFill option.
+ */
+bool ASBeautifier::getEmptyLineFill(void)
+{
+ return emptyLineFill;
+}
+
+/**
+ * check if there are any indented lines ready to be read by nextLine()
+ *
+ * @return are there any indented lines ready?
+ */
+bool ASBeautifier::hasMoreLines() const
+{
+ return sourceIterator->hasMoreLines();
+}
+
+/**
+ * get the next indented line.
+ *
+ * @return indented line.
+ */
+string ASBeautifier::nextLine()
+{
+ return beautify(sourceIterator->nextLine());
+}
+
+/**
+ * beautify a line of source code.
+ * every line of source code in a source code file should be sent
+ * one after the other to the beautify method.
+ *
+ * @return the indented line.
+ * @param originalLine the original unindented line.
+ */
+string ASBeautifier::beautify(const string &originalLine)
+{
+ string line;
+ bool isInLineComment = false;
+ bool lineStartsInComment = false;
+ bool isInClass = false;
+ bool isInSwitch = false;
+ bool isInOperator = false;
+ bool isSpecialChar = false;
+ bool haveCaseIndent = false;
+ bool haveAssignmentThisLine = false;
+ bool lineBeginsWithBracket = false;
+ bool closingBracketReached = false;
+ bool shouldIndentBrackettedLine = true;
+ bool previousLineProbation = (probationHeader != NULL);
+ bool isInQuoteContinuation = isInVerbatimQuote | haveLineContinuationChar;
+ char ch = ' ';
+ char prevCh;
+ char tempCh;
+ int tabCount = 0;
+ int spaceTabCount = 0;
+ int lineOpeningBlocksNum = 0;
+ int lineClosingBlocksNum = 0;
+ int tabIncrementIn = 0;
+ int i;
+ int iPrelim;
+ string outBuffer; // the newly idented line is buffered here
+ const string *lastLineHeader = NULL;
+
+ currentHeader = NULL;
+ lineStartsInComment = isInComment;
+ blockCommentNoBeautify = blockCommentNoIndent;
+ isInAsmOneLine = false;
+ lineOpensComment = false;
+ previousLineProbationTab = false;
+ haveLineContinuationChar = false;
+
+ // handle and remove white spaces around the line:
+ // If not in comment, first find out size of white space before line,
+ // so that possible comments starting in the line continue in
+ // relation to the preliminary white-space.
+ if (isInQuoteContinuation)
+ {
+ // trim a single space added by ASFormatter, otherwise leave it alone
+ if (!(originalLine.length() == 1 && originalLine[0] == ' '))
+ line = originalLine;
+ }
+ else if (isInComment || isInBeautifySQL)
+ {
+ // trim the end of comment and SQL lines
+ line = originalLine;
+ size_t trimEnd = line.find_last_not_of(" \t");
+ if (trimEnd == string::npos)
+ trimEnd = 0;
+ else
+ trimEnd++;
+ if (trimEnd < line.length())
+ line.erase(trimEnd);
+ }
+ else
+ {
+ line = trim(originalLine);
+ if (line.length() > 0 && line[0] == '{')
+ lineBeginsWithBracket = true;
+
+ isInHorstmannComment = false;
+ size_t j = line.find_first_not_of(" \t{");
+ if (j != string::npos && line.compare(j, 2, "/*") == 0)
+ {
+ lineOpensComment = true;
+ size_t k = line.find_first_not_of(" \t");
+ if (k != string::npos && line.compare(k, 1, "{") == 0)
+ isInHorstmannComment = true;
+ }
+ }
+
+ if (line.length() == 0)
+ {
+ if (backslashEndsPrevLine) // must continue to clear variables
+ line = ' ';
+ else if (emptyLineFill && !isInQuoteContinuation && headerStack->size() > 0)
+ return preLineWS(prevFinalLineSpaceTabCount, prevFinalLineTabCount);
+ else
+ return line;
+ }
+
+ // handle preprocessor commands
+ // except C# region and endregion
+
+ if (!isInComment
+ && (line[0] == '#' || backslashEndsPrevLine)
+ && line.compare(0, 7, "#region") != 0
+ && line.compare(0, 10, "#endregion") != 0)
+ {
+ if (line[0] == '#')
+ {
+ string preproc = trim(string(line.c_str() + 1));
+
+ // When finding a multi-lined #define statement, the original beautifier
+ // 1. sets its isInDefineDefinition flag
+ // 2. clones a new beautifier that will be used for the actual indentation
+ // of the #define. This clone is put into the activeBeautifierStack in order
+ // to be called for the actual indentation.
+ // The original beautifier will have isInDefineDefinition = true, isInDefine = false
+ // The cloned beautifier will have isInDefineDefinition = true, isInDefine = true
+ if (preprocessorIndent && preproc.compare(0, 6, "define") == 0 && line[line.length() - 1] == '\\')
+ {
+ if (!isInDefineDefinition)
+ {
+ ASBeautifier *defineBeautifier;
+
+ // this is the original beautifier
+ isInDefineDefinition = true;
+
+ // push a new beautifier into the active stack
+ // this beautifier will be used for the indentation of this define
+ defineBeautifier = new ASBeautifier(*this);
+ activeBeautifierStack->push_back(defineBeautifier);
+ }
+ else
+ {
+ // the is the cloned beautifier that is in charge of indenting the #define.
+ isInDefine = true;
+ }
+ }
+ else if (preproc.compare(0, 2, "if") == 0)
+ {
+ // push a new beautifier into the stack
+ waitingBeautifierStackLengthStack->push_back(waitingBeautifierStack->size());
+ activeBeautifierStackLengthStack->push_back(activeBeautifierStack->size());
+ waitingBeautifierStack->push_back(new ASBeautifier(*this));
+ }
+ else if (preproc.compare(0, 4/*2*/, "else") == 0)
+ {
+ if (waitingBeautifierStack && !waitingBeautifierStack->empty())
+ {
+ // MOVE current waiting beautifier to active stack.
+ activeBeautifierStack->push_back(waitingBeautifierStack->back());
+ waitingBeautifierStack->pop_back();
+ }
+ }
+ else if (preproc.compare(0, 4, "elif") == 0)
+ {
+ if (waitingBeautifierStack && !waitingBeautifierStack->empty())
+ {
+ // append a COPY current waiting beautifier to active stack, WITHOUT deleting the original.
+ activeBeautifierStack->push_back(new ASBeautifier(*(waitingBeautifierStack->back())));
+ }
+ }
+ else if (preproc.compare(0, 5, "endif") == 0)
+ {
+ int stackLength;
+ ASBeautifier *beautifier;
+
+ if (waitingBeautifierStackLengthStack && !waitingBeautifierStackLengthStack->empty())
+ {
+ stackLength = waitingBeautifierStackLengthStack->back();
+ waitingBeautifierStackLengthStack->pop_back();
+ while ((int) waitingBeautifierStack->size() > stackLength)
+ {
+ beautifier = waitingBeautifierStack->back();
+ waitingBeautifierStack->pop_back();
+ delete beautifier;
+ }
+ }
+
+ if (!activeBeautifierStackLengthStack->empty())
+ {
+ stackLength = activeBeautifierStackLengthStack->back();
+ activeBeautifierStackLengthStack->pop_back();
+ while ((int) activeBeautifierStack->size() > stackLength)
+ {
+ beautifier = activeBeautifierStack->back();
+ activeBeautifierStack->pop_back();
+ delete beautifier;
+ }
+ }
+ }
+ }
+
+ // check if the last char is a backslash
+ if (line.length() > 0)
+ backslashEndsPrevLine = (line[line.length() - 1] == '\\');
+ else
+ backslashEndsPrevLine = false;
+
+ // check if this line ends a multi-line #define
+ // if so, use the #define's cloned beautifier for the line's indentation
+ // and then remove it from the active beautifier stack and delete it.
+ if (!backslashEndsPrevLine && isInDefineDefinition && !isInDefine)
+ {
+ string beautifiedLine;
+ ASBeautifier *defineBeautifier;
+
+ isInDefineDefinition = false;
+ defineBeautifier = activeBeautifierStack->back();
+ activeBeautifierStack->pop_back();
+
+ beautifiedLine = defineBeautifier->beautify(line);
+ delete defineBeautifier;
+ return beautifiedLine;
+ }
+
+ // unless this is a multi-line #define, return this precompiler line as is.
+ if (!isInDefine && !isInDefineDefinition)
+ return originalLine;
+ }
+
+ // if there exists any worker beautifier in the activeBeautifierStack,
+ // then use it instead of me to indent the current line.
+ // variables set by ASFormatter must be updated.
+ if (!isInDefine && activeBeautifierStack != NULL && !activeBeautifierStack->empty())
+ {
+ activeBeautifierStack->back()->inLineNumber = inLineNumber;
+ activeBeautifierStack->back()->horstmannIndentInStatement = horstmannIndentInStatement;
+ activeBeautifierStack->back()->nonInStatementBracket = nonInStatementBracket;
+ activeBeautifierStack->back()->lineCommentNoBeautify = lineCommentNoBeautify;
+ activeBeautifierStack->back()->isNonInStatementArray = isNonInStatementArray;
+ activeBeautifierStack->back()->isSharpAccessor = isSharpAccessor;
+ activeBeautifierStack->back()->isSharpDelegate = isSharpDelegate;
+ activeBeautifierStack->back()->isInExtern = isInExtern;
+ activeBeautifierStack->back()->isInBeautifySQL = isInBeautifySQL;
+ activeBeautifierStack->back()->isInIndentableStruct = isInIndentableStruct;
+ // must return originalLine not the trimmed line
+ return activeBeautifierStack->back()->beautify(originalLine);
+ }
+
+ // calculate preliminary indentation based on data from past lines
+
+ if (!inStatementIndentStack->empty())
+ spaceTabCount = inStatementIndentStack->back();
+
+ for (i = 0; i < (int) headerStack->size(); i++)
+ {
+ isInClass = false;
+
+ if (blockIndent)
+ {
+ // do NOT indent opening block for these headers
+ if (!((*headerStack)[i] == &AS_NAMESPACE
+ || (*headerStack)[i] == &AS_CLASS
+ || (*headerStack)[i] == &AS_STRUCT
+ || (*headerStack)[i] == &AS_UNION
+ || (*headerStack)[i] == &AS_CONST
+ || (*headerStack)[i] == &AS_INTERFACE
+ || (*headerStack)[i] == &AS_THROWS
+ || (*headerStack)[i] == &AS_STATIC))
+ ++tabCount;
+ }
+ else if (!(i > 0 && (*headerStack)[i-1] != &AS_OPEN_BRACKET
+ && (*headerStack)[i] == &AS_OPEN_BRACKET))
+ ++tabCount;
+
+ if (!isJavaStyle() && !namespaceIndent && i >= 1
+ && (*headerStack)[i-1] == &AS_NAMESPACE
+ && (*headerStack)[i] == &AS_OPEN_BRACKET)
+ --tabCount;
+
+ if (isCStyle() && i >= 1
+ && (*headerStack)[i-1] == &AS_CLASS
+ && (*headerStack)[i] == &AS_OPEN_BRACKET)
+ {
+ if (classIndent)
+ ++tabCount;
+ isInClass = true;
+ }
+
+ // is the switchIndent option is on, indent switch statements an additional indent.
+ else if (switchIndent && i > 1
+ && (*headerStack)[i-1] == &AS_SWITCH
+ && (*headerStack)[i] == &AS_OPEN_BRACKET)
+ {
+ ++tabCount;
+ isInSwitch = true;
+ }
+
+ } // end of for loop * end of for loop * end of for loop * end of for loop * end of for loop *
+
+ iPrelim = i;
+
+ if (!lineStartsInComment
+ && isCStyle()
+ && isInClass
+ && classIndent
+ && headerStack->size() >= 2
+ && (*headerStack)[headerStack->size()-2] == &AS_CLASS
+ && (*headerStack)[headerStack->size()-1] == &AS_OPEN_BRACKET
+ && line[0] == '}'
+ && bracketBlockStateStack->back() == true)
+ --tabCount;
+
+ else if (!lineStartsInComment
+ && isInSwitch
+ && switchIndent
+ && headerStack->size() >= 2
+ && (*headerStack)[headerStack->size()-2] == &AS_SWITCH
+ && (*headerStack)[headerStack->size()-1] == &AS_OPEN_BRACKET
+ && line[0] == '}')
+ --tabCount;
+
+ if (isInClassInitializer)
+ {
+ if (lineStartsInComment || lineOpensComment)
+ {
+ if (!lineBeginsWithBracket)
+ tabCount--;
+ }
+ else if (isCStyle() && !isClassAccessModifier(line))
+ {
+ isInClassHeaderTab = true;
+ tabCount += classInitializerTabs;
+ }
+ else if (blockIndent)
+ {
+ if (!lineBeginsWithBracket)
+ tabCount++;
+ }
+ }
+ // handle special case of indented horstmann brackets
+ else if (lineStartsInComment && isInHorstmannComment && bracketIndent)
+ tabCount++;
+
+ // handle special case of horstmann comment in an indented class statement
+ if (isInClass
+ && classIndent
+ && isInHorstmannComment
+ && !lineOpensComment
+ && headerStack->size() >= 2
+ && (*headerStack)[headerStack->size()-2] == &AS_CLASS)
+ --tabCount;
+
+ if (isInConditional)
+ {
+ --tabCount;
+ }
+
+
+ // parse characters in the current line.
+
+ for (i = 0; i < (int) line.length(); i++)
+ {
+ outBuffer.append(1, line[i]);
+
+ tempCh = line[i];
+ prevCh = ch;
+ ch = tempCh;
+
+ if (isInBeautifySQL)
+ continue;
+
+ if (isWhiteSpace(ch))
+ {
+ if (ch == '\t')
+ tabIncrementIn += convertTabToSpaces(i, tabIncrementIn);
+ continue;
+ }
+
+ // handle special characters (i.e. backslash+character such as \n, \t, ...)
+
+ if (isInQuote && !isInVerbatimQuote)
+ {
+ if (isSpecialChar)
+ {
+ isSpecialChar = false;
+ continue;
+ }
+ if (line.compare(i, 2, "\\\\") == 0)
+ {
+ outBuffer.append(1, '\\');
+ i++;
+ continue;
+ }
+ if (ch == '\\')
+ {
+ if (peekNextChar(line, i) == ' ') // is this '\' at end of line
+ haveLineContinuationChar = true;
+ else
+ isSpecialChar = true;
+ continue;
+ }
+ }
+ else if (isInDefine && ch == '\\')
+ continue;
+
+ // handle quotes (such as 'x' and "Hello Dolly")
+ if (!(isInComment || isInLineComment) && (ch == '"' || ch == '\''))
+ {
+ if (!isInQuote)
+ {
+ quoteChar = ch;
+ isInQuote = true;
+ if (isSharpStyle() && prevCh == '@')
+ isInVerbatimQuote = true;
+ }
+ else if (isInVerbatimQuote && ch == '"')
+ {
+ if (peekNextChar(line, i) == '"') // check consecutive quotes
+ {
+ outBuffer.append(1, '"');
+ i++;
+ }
+ else
+ {
+ isInQuote = false;
+ isInVerbatimQuote = false;
+ }
+ }
+ else if (quoteChar == ch)
+ {
+ isInQuote = false;
+ isInStatement = true;
+ continue;
+ }
+ }
+ if (isInQuote)
+ continue;
+
+ // handle comments
+
+ if (!(isInComment || isInLineComment) && line.compare(i, 2, "//") == 0)
+ {
+ isInLineComment = true;
+ outBuffer.append(1, '/');
+ i++;
+ continue;
+ }
+ else if (!(isInComment || isInLineComment) && line.compare(i, 2, "/*") == 0)
+ {
+ isInComment = true;
+ outBuffer.append(1, '*');
+ i++;
+ if (!lineOpensComment) // does line start with comment?
+ blockCommentNoIndent = true; // if no, cannot indent continuation lines
+ continue;
+ }
+ else if ((isInComment || isInLineComment) && line.compare(i, 2, "*/") == 0)
+ {
+ isInComment = false;
+ outBuffer.append(1, '/');
+ i++;
+ blockCommentNoIndent = false; // ok to indent next comment
+ continue;
+ }
+ // treat C# '#region' and '#endregion' statements as a line comment
+ else if (isSharpStyle() &&
+ (line.compare(i, 7, "#region") == 0 || line.compare(i, 10, "#endregion") == 0))
+ {
+ isInLineComment = true;
+ }
+
+ if (isInComment || isInLineComment)
+ {
+ // append rest of the comment up to the comment end
+ while (i+1 < (int) line.length()
+ && line.compare(i+1, 2, "*/") != 0)
+ outBuffer.append(1, line[++i]);
+ continue;
+ }
+
+ // if we have reached this far then we are NOT in a comment or string of special character...
+
+ // SQL if formatted in ASEnhancer
+ if (isInBeautifySQL)
+ continue;
+
+ if (probationHeader != NULL)
+ {
+ if (((probationHeader == &AS_STATIC || probationHeader == &AS_CONST) && ch == '{')
+ || (probationHeader == &AS_SYNCHRONIZED && ch == '('))
+ {
+ // insert the probation header as a new header
+ isInHeader = true;
+ headerStack->push_back(probationHeader);
+
+ // handle the specific probation header
+ isInConditional = (probationHeader == &AS_SYNCHRONIZED);
+
+ isInStatement = false;
+ // if the probation comes from the previous line, then indent by 1 tab count.
+ if (previousLineProbation
+ && ch == '{'
+ && !(blockIndent
+ && (probationHeader == &AS_CONST || probationHeader == &AS_STATIC)))
+ {
+ tabCount++;
+ previousLineProbationTab = true;
+ }
+ previousLineProbation = false;
+ }
+
+ // dismiss the probation header
+ probationHeader = NULL;
+ }
+
+ prevNonSpaceCh = currentNonSpaceCh;
+ currentNonSpaceCh = ch;
+ if (!isLegalNameChar(ch) && ch != ',' && ch != ';')
+ {
+ prevNonLegalCh = currentNonLegalCh;
+ currentNonLegalCh = ch;
+ }
+
+ if (isInHeader)
+ {
+ isInHeader = false;
+ currentHeader = headerStack->back();
+ }
+ else
+ currentHeader = NULL;
+
+ if (isCStyle() && isInTemplate
+ && (ch == '<' || ch == '>')
+ && findOperator(line, i, nonAssignmentOperators) == NULL)
+ {
+ if (ch == '<')
+ {
+ ++templateDepth;
+ }
+ else if (ch == '>')
+ {
+ if (--templateDepth <= 0)
+ {
+ if (isInTemplate)
+ ch = ';';
+ else
+ ch = 't';
+ isInTemplate = false;
+ templateDepth = 0;
+ }
+ }
+ }
+
+ // handle parenthesies
+ if (ch == '(' || ch == '[' || ch == ')' || ch == ']')
+ {
+ if (ch == '(' || ch == '[')
+ {
+ isInOperator = false;
+ // if have a struct header, this is a declaration not a definition
+ if (ch == '('
+ && (isInClassInitializer || isInClassHeaderTab)
+ && headerStack->size() > 0
+ && headerStack->back() == &AS_STRUCT)
+ {
+ headerStack->pop_back();
+ isInClassInitializer = false;
+ // -1 for isInClassInitializer, -2 for isInClassHeaderTab
+ if (isInClassHeaderTab)
+ {
+ tabCount -= (1 + classInitializerTabs);
+ isInClassHeaderTab = false;
+ }
+ if (tabCount < 0)
+ tabCount = 0;
+ }
+
+ if (parenDepth == 0)
+ {
+ parenStatementStack->push_back(isInStatement);
+ isInStatement = true;
+ }
+ parenDepth++;
+
+ inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
+
+ if (currentHeader != NULL)
+ registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, minConditionalIndent/*indentLength*2*/, true);
+ else
+ registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, true);
+ }
+ else if (ch == ')' || ch == ']')
+ {
+ parenDepth--;
+ if (parenDepth == 0)
+ {
+ if (!parenStatementStack->empty()) // in case of unmatched closing parens
+ {
+ isInStatement = parenStatementStack->back();
+ parenStatementStack->pop_back();
+ }
+ ch = ' ';
+ isInAsm = false;
+ isInConditional = false;
+ }
+
+ if (!inStatementIndentStackSizeStack->empty())
+ {
+ int previousIndentStackSize = inStatementIndentStackSizeStack->back();
+ inStatementIndentStackSizeStack->pop_back();
+ while (previousIndentStackSize < (int) inStatementIndentStack->size())
+ inStatementIndentStack->pop_back();
+
+ if (!parenIndentStack->empty())
+ {
+ int poppedIndent = parenIndentStack->back();
+ parenIndentStack->pop_back();
+
+ if (i == 0)
+ spaceTabCount = poppedIndent;
+ }
+ }
+ }
+
+ continue;
+ }
+
+
+ if (ch == '{')
+ {
+ // first, check if '{' is a block-opener or an static-array opener
+ bool isBlockOpener = ((prevNonSpaceCh == '{' && bracketBlockStateStack->back())
+ || prevNonSpaceCh == '}'
+ || prevNonSpaceCh == ')'
+ || prevNonSpaceCh == ';'
+ || peekNextChar(line, i) == '{'
+ || isInClassInitializer
+ || isNonInStatementArray
+ || isSharpAccessor
+ || isSharpDelegate
+ || isInExtern
+ || (isInDefine &&
+ (prevNonSpaceCh == '('
+ || isLegalNameChar(prevNonSpaceCh))));
+
+ // remove inStatementIndent for C++ class initializer
+ if (isInClassInitializer)
+ {
+ if (inStatementIndentStack->size() > 0)
+ inStatementIndentStack->pop_back();
+ isInStatement = false;
+ if (lineBeginsWithBracket)
+ spaceTabCount = 0;
+ isInClassInitializer = false;
+ }
+
+ if (!isBlockOpener && currentHeader != NULL)
+ {
+ for (size_t n = 0; n < nonParenHeaders->size(); n++)
+ if (currentHeader == (*nonParenHeaders)[n])
+ {
+ isBlockOpener = true;
+ break;
+ }
+ }
+
+ bracketBlockStateStack->push_back(isBlockOpener);
+
+ if (!isBlockOpener)
+ {
+ inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
+ registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, true);
+ parenDepth++;
+ if (i == 0)
+ shouldIndentBrackettedLine = false;
+
+ continue;
+ }
+
+ // this bracket is a block opener...
+
+ ++lineOpeningBlocksNum;
+
+ if (isInClassHeaderTab)
+ {
+ isInClassHeaderTab = false;
+ // decrease tab count if bracket is broken
+ size_t firstChar = line.find_first_not_of(" \t");
+ if (firstChar != string::npos
+ && line[firstChar] == '{'
+ && (int) firstChar == i)
+ {
+ tabCount -= classInitializerTabs;
+ // decrease one more if an empty class
+ if (headerStack->size() > 0
+ && (*headerStack).back() == &AS_CLASS)
+ {
+ int nextChar = getNextProgramCharDistance(line, i);
+ if (line[nextChar] == '}')
+ tabCount--;
+ }
+ }
+ }
+
+ if (bracketIndent && !namespaceIndent && headerStack->size() > 0
+ && (*headerStack).back() == &AS_NAMESPACE)
+ {
+ shouldIndentBrackettedLine = false;
+ tabCount--;
+ }
+
+ // an indentable struct is treated like a class in the header stack
+ if (headerStack->size() > 0
+ && (*headerStack).back() == &AS_STRUCT
+ && isInIndentableStruct)
+ (*headerStack).back() = &AS_CLASS;
+
+ blockParenDepthStack->push_back(parenDepth);
+ blockStatementStack->push_back(isInStatement);
+
+ inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
+ if (inStatementIndentStack->size() > 0)
+ {
+ spaceTabCount = 0;
+ inStatementIndentStack->back() = 0;
+ }
+
+ blockTabCount += isInStatement ? 1 : 0;
+ parenDepth = 0;
+ isInStatement = false;
+
+ tempStacks->push_back(new vector<const string*>);
+ headerStack->push_back(&AS_OPEN_BRACKET);
+ lastLineHeader = &AS_OPEN_BRACKET;
+
+ continue;
+ }
+
+ //check if a header has been reached
+ bool isPotentialHeader = isCharPotentialHeader(line, i);
+
+ if (isPotentialHeader)
+ {
+ const string *newHeader = findHeader(line, i, headers);
+
+ if (newHeader != NULL)
+ {
+ char peekChar = peekNextChar(line, i + newHeader->length() - 1);
+
+ // is not a header if part of a definition
+ if (peekChar == ',' || peekChar == ')')
+ newHeader = NULL;
+ // the following accessor definitions are NOT headers
+ // goto default; is NOT a header
+ // default(int) keyword in C# is NOT a header
+ else if ((newHeader == &AS_GET || newHeader == &AS_SET || newHeader == &AS_DEFAULT)
+ && (peekChar == ';' || peekChar == '('))
+ {
+ newHeader = NULL;
+ }
+ }
+
+ if (newHeader != NULL)
+ {
+ // if we reached here, then this is a header...
+ bool isIndentableHeader = true;
+
+ isInHeader = true;
+
+ vector<const string*> *lastTempStack;
+ if (tempStacks->empty())
+ lastTempStack = NULL;
+ else
+ lastTempStack = tempStacks->back();
+
+ // if a new block is opened, push a new stack into tempStacks to hold the
+ // future list of headers in the new block.
+
+ // take care of the special case: 'else if (...)'
+ if (newHeader == &AS_IF && lastLineHeader == &AS_ELSE)
+ {
+ headerStack->pop_back();
+ }
+
+ // take care of 'else'
+ else if (newHeader == &AS_ELSE)
+ {
+ if (lastTempStack != NULL)
+ {
+ int indexOfIf = indexOf(*lastTempStack, &AS_IF);
+ if (indexOfIf != -1)
+ {
+ // recreate the header list in headerStack up to the previous 'if'
+ // from the temporary snapshot stored in lastTempStack.
+ int restackSize = lastTempStack->size() - indexOfIf - 1;
+ for (int r = 0; r < restackSize; r++)
+ {
+ headerStack->push_back(lastTempStack->back());
+ lastTempStack->pop_back();
+ }
+ if (!closingBracketReached)
+ tabCount += restackSize;
+ }
+ /*
+ * If the above if is not true, i.e. no 'if' before the 'else',
+ * then nothing beautiful will come out of this...
+ * I should think about inserting an Exception here to notify the caller of this...
+ */
+ }
+ }
+
+ // check if 'while' closes a previous 'do'
+ else if (newHeader == &AS_WHILE)
+ {
+ if (lastTempStack != NULL)
+ {
+ int indexOfDo = indexOf(*lastTempStack, &AS_DO);
+ if (indexOfDo != -1)
+ {
+ // recreate the header list in headerStack up to the previous 'do'
+ // from the temporary snapshot stored in lastTempStack.
+ int restackSize = lastTempStack->size() - indexOfDo - 1;
+ for (int r = 0; r < restackSize; r++)
+ {
+ headerStack->push_back(lastTempStack->back());
+ lastTempStack->pop_back();
+ }
+ if (!closingBracketReached)
+ tabCount += restackSize;
+ }
+ }
+ }
+ // check if 'catch' closes a previous 'try' or 'catch'
+ else if (newHeader == &AS_CATCH || newHeader == &AS_FINALLY)
+ {
+ if (lastTempStack != NULL)
+ {
+ int indexOfTry = indexOf(*lastTempStack, &AS_TRY);
+ if (indexOfTry == -1)
+ indexOfTry = indexOf(*lastTempStack, &AS_CATCH);
+ if (indexOfTry != -1)
+ {
+ // recreate the header list in headerStack up to the previous 'try'
+ // from the temporary snapshot stored in lastTempStack.
+ int restackSize = lastTempStack->size() - indexOfTry - 1;
+ for (int r = 0; r < restackSize; r++)
+ {
+ headerStack->push_back(lastTempStack->back());
+ lastTempStack->pop_back();
+ }
+
+ if (!closingBracketReached)
+ tabCount += restackSize;
+ }
+ }
+ }
+ else if (newHeader == &AS_CASE)
+ {
+ isInCase = true;
+ if (!haveCaseIndent)
+ {
+ haveCaseIndent = true;
+ if (!lineBeginsWithBracket)
+ --tabCount;
+ }
+ }
+ else if (newHeader == &AS_DEFAULT)
+ {
+ isInCase = true;
+ --tabCount;
+ }
+ else if (newHeader == &AS_STATIC
+ || newHeader == &AS_SYNCHRONIZED
+ || (newHeader == &AS_CONST && isCStyle()))
+ {
+ if (!headerStack->empty() &&
+ (headerStack->back() == &AS_STATIC
+ || headerStack->back() == &AS_SYNCHRONIZED
+ || headerStack->back() == &AS_CONST))
+ {
+ isIndentableHeader = false;
+ }
+ else
+ {
+ isIndentableHeader = false;
+ probationHeader = newHeader;
+ }
+ }
+ else if (newHeader == &AS_CONST)
+ {
+ isIndentableHeader = false;
+ }
+ else if (newHeader == &AS_TEMPLATE)
+ {
+ if (isCStyle())
+ isInTemplate = true;
+ isIndentableHeader = false;
+ }
+
+ if (isIndentableHeader)
+ {
+ headerStack->push_back(newHeader);
+ isInStatement = false;
+ if (indexOf(*nonParenHeaders, newHeader) == -1)
+ {
+ isInConditional = true;
+ }
+ lastLineHeader = newHeader;
+ }
+ else
+ isInHeader = false;
+
+ outBuffer.append(newHeader->substr(1));
+ i += newHeader->length() - 1;
+
+ continue;
+ } // newHeader != NULL
+
+ if (isCStyle() && findKeyword(line, i, AS_ENUM))
+ isInEnum = true;
+
+ } // isPotentialHeader
+
+ if (ch == '?')
+ isInQuestion = true;
+
+ // special handling of 'case' statements
+ if (ch == ':')
+ {
+ if ((int) line.length() > i + 1 && line[i+1] == ':') // look for ::
+ {
+ ++i;
+ outBuffer.append(1, ':');
+ ch = ' ';
+ continue;
+ }
+
+ else if (isInQuestion)
+ {
+ isInQuestion = false;
+ }
+
+ else if (isCStyle() && isInClassInitializer)
+ {
+ // found a 'class A : public B' definition
+ // so do nothing special
+ }
+
+ else if (isCStyle()
+ && (isInAsm || isInAsmOneLine || isInAsmBlock))
+ {
+ // do nothing special
+ }
+
+ else if (isCStyle() && isdigit(peekNextChar(line, i)))
+ {
+ // found a bit field
+ // so do nothing special
+ }
+
+ else if (isCStyle() && isInClass && prevNonSpaceCh != ')')
+ {
+ // found a 'private:' or 'public:' inside a class definition
+ --tabCount;
+ }
+
+ else if (isCStyle() && prevNonSpaceCh == ')' && !isInCase)
+ {
+ isInClassInitializer = true;
+ if (i == 0)
+ tabCount += classInitializerTabs;
+ }
+
+ else if (isJavaStyle() && lastLineHeader == &AS_FOR)
+ {
+ // found a java for-each statement
+ // so do nothing special
+ }
+
+ else
+ {
+ currentNonSpaceCh = ';'; // so that brackets after the ':' will appear as block-openers
+ if (isInCase)
+ {
+ isInCase = false;
+ ch = ';'; // from here on, treat char as ';'
+ }
+ else if (isCStyle() || (isSharpStyle() && peekNextChar(line, i) == ';')) // is in a label (e.g. 'label1:')
+ {
+ if (labelIndent)
+ --tabCount; // unindent label by one indent
+ else if (!lineBeginsWithBracket)
+ tabCount = 0; // completely flush indent to left
+ }
+ }
+ }
+
+ if ((ch == ';' || (parenDepth > 0 && ch == ',')) && !inStatementIndentStackSizeStack->empty())
+ while ((int) inStatementIndentStackSizeStack->back() + (parenDepth > 0 ? 1 : 0)
+ < (int) inStatementIndentStack->size())
+ inStatementIndentStack->pop_back();
+
+ // handle commas
+ // previous "isInStatement" will be from an assignment operator
+ if (ch == ',' && parenDepth == 0 && !isInStatement && !isNonInStatementArray)
+ {
+ // is comma at end of line
+ size_t nextChar = line.find_first_not_of(" \t", i + 1);
+ if (nextChar != string::npos)
+ {
+ if (line.compare(nextChar, 2, "//") == 0
+ || line.compare(nextChar, 2, "/*") == 0)
+ nextChar = string::npos;
+ }
+ // register indent
+ if (nextChar == string::npos)
+ {
+ // register indent at first word after the colon of a C++ class initializer
+ if (isInClassInitializer)
+ {
+ size_t firstChar = line.find_first_not_of(" \t");
+ if (firstChar != string::npos && line[firstChar] == ':')
+ {
+ size_t firstWord = line.find_first_not_of(" \t", firstChar + 1);
+ if (firstChar != string::npos)
+ {
+ int inStatementIndent = firstWord + spaceTabCount + tabIncrementIn;
+ inStatementIndentStack->push_back(inStatementIndent);
+ isInStatement = true;
+ }
+ }
+ }
+ // register indent at previous word
+ else
+ {
+ int prevWord = getInStatementIndentComma(line, i);
+ int inStatementIndent = prevWord + spaceTabCount + tabIncrementIn;
+ inStatementIndentStack->push_back(inStatementIndent);
+ isInStatement = true;
+ }
+ }
+ }
+
+ // handle ends of statements
+ if ((ch == ';' && parenDepth == 0) || ch == '}')
+ {
+ if (ch == '}')
+ {
+ // first check if this '}' closes a previous block, or a static array...
+ if (!bracketBlockStateStack->empty())
+ {
+ bool bracketBlockState = bracketBlockStateStack->back();
+ bracketBlockStateStack->pop_back();
+ if (!bracketBlockState)
+ {
+ if (!inStatementIndentStackSizeStack->empty())
+ {
+ // this bracket is a static array
+
+ int previousIndentStackSize = inStatementIndentStackSizeStack->back();
+ inStatementIndentStackSizeStack->pop_back();
+ while (previousIndentStackSize < (int) inStatementIndentStack->size())
+ inStatementIndentStack->pop_back();
+ parenDepth--;
+ if (i == 0)
+ shouldIndentBrackettedLine = false;
+
+ if (!parenIndentStack->empty())
+ {
+ int poppedIndent = parenIndentStack->back();
+ parenIndentStack->pop_back();
+ if (i == 0)
+ spaceTabCount = poppedIndent;
+ }
+ }
+ continue;
+ }
+ }
+
+ // this bracket is block closer...
+
+ ++lineClosingBlocksNum;
+
+ if (!inStatementIndentStackSizeStack->empty())
+ inStatementIndentStackSizeStack->pop_back();
+
+ if (!blockParenDepthStack->empty())
+ {
+ parenDepth = blockParenDepthStack->back();
+ blockParenDepthStack->pop_back();
+ isInStatement = blockStatementStack->back();
+ blockStatementStack->pop_back();
+
+ if (isInStatement)
+ blockTabCount--;
+ }
+
+ closingBracketReached = true;
+ isInAsmOneLine = false;
+
+ // added for release 1.24
+ // TODO: remove at the appropriate time
+ assert(isInAsm == false);
+ assert(isInAsmOneLine == false);
+ assert(isInQuote == false);
+ isInAsm = isInAsmOneLine = isInQuote = false;
+ // end remove
+
+ int headerPlace = indexOf(*headerStack, &AS_OPEN_BRACKET);
+ if (headerPlace != -1)
+ {
+ const string *popped = headerStack->back();
+ while (popped != &AS_OPEN_BRACKET)
+ {
+ headerStack->pop_back();
+ popped = headerStack->back();
+ }
+ headerStack->pop_back();
+
+ // do not indent namespace bracket unless namespaces are indented
+ if (!namespaceIndent && headerStack->size() > 0
+ && (*headerStack).back() == &AS_NAMESPACE)
+ shouldIndentBrackettedLine = false;
+
+ if (!tempStacks->empty())
+ {
+ vector<const string*> *temp = tempStacks->back();
+ tempStacks->pop_back();
+ delete temp;
+ }
+ }
+
+
+ ch = ' '; // needed due to cases such as '}else{', so that headers ('else' tn tih case) will be identified...
+ }
+
+ /*
+ * Create a temporary snapshot of the current block's header-list in the
+ * uppermost inner stack in tempStacks, and clear the headerStack up to
+ * the begining of the block.
+ * Thus, the next future statement will think it comes one indent past
+ * the block's '{' unless it specifically checks for a companion-header
+ * (such as a previous 'if' for an 'else' header) within the tempStacks,
+ * and recreates the temporary snapshot by manipulating the tempStacks.
+ */
+ if (!tempStacks->back()->empty())
+ while (!tempStacks->back()->empty())
+ tempStacks->back()->pop_back();
+ while (!headerStack->empty() && headerStack->back() != &AS_OPEN_BRACKET)
+ {
+ tempStacks->back()->push_back(headerStack->back());
+ headerStack->pop_back();
+ }
+
+ if (parenDepth == 0 && ch == ';')
+ isInStatement = false;
+
+ previousLastLineHeader = NULL;
+ isInClassInitializer = false;
+ isInEnum = false;
+ isInQuestion = false;
+
+ continue;
+ }
+
+ if (isPotentialHeader)
+ {
+ // check for preBlockStatements in C/C++ ONLY if not within parenthesies
+ // (otherwise 'struct XXX' statements would be wrongly interpreted...)
+ if (!isInTemplate && !(isCStyle() && parenDepth > 0))
+ {
+ const string *newHeader = findHeader(line, i, preBlockStatements);
+ if (newHeader != NULL
+ && !(isCStyle() && newHeader == &AS_CLASS && isInEnum)) // is it 'enum class'
+ {
+ isInClassInitializer = true;
+
+ if (!isSharpStyle())
+ headerStack->push_back(newHeader);
+ // do not need 'where' in the headerStack
+ // do not need second 'class' statement in a row
+ else if (!(newHeader == &AS_WHERE
+ || (newHeader == &AS_CLASS
+ && headerStack->size() > 0
+ && headerStack->back() == &AS_CLASS)))
+ headerStack->push_back(newHeader);
+
+ outBuffer.append(newHeader->substr(1));
+ i += newHeader->length() - 1;
+ continue;
+ }
+ }
+ const string *foundIndentableHeader = findHeader(line, i, indentableHeaders);
+
+ if (foundIndentableHeader != NULL)
+ {
+ // must bypass the header before registering the in statement
+ outBuffer.append(foundIndentableHeader->substr(1));
+ i += foundIndentableHeader->length() - 1;
+ if (!isInOperator && !isInTemplate && !isNonInStatementArray)
+ {
+ registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, false);
+ isInStatement = true;
+ }
+ continue;
+ }
+
+ if (isCStyle() && findKeyword(line, i, AS_OPERATOR))
+ isInOperator = true;
+
+ // "new" operator is a pointer, not a calculation
+ if (findKeyword(line, i, AS_NEW))
+ {
+ if (prevNonSpaceCh == '=' && isInStatement && !inStatementIndentStack->empty())
+ inStatementIndentStack->back() = 0;
+ }
+
+ if (isCStyle())
+ {
+ if (findKeyword(line, i, AS_ASM)
+ || findKeyword(line, i, AS__ASM__))
+ {
+ isInAsm = true;
+ }
+ else if (findKeyword(line, i, AS_MS_ASM) // microsoft specific
+ || findKeyword(line, i, AS_MS__ASM))
+ {
+ int index = 4;
+ if (peekNextChar(line, i) == '_') // check for __asm
+ index = 5;
+
+ char peekedChar = ASBase::peekNextChar(line, i + index);
+ if (peekedChar == '{' || peekedChar == ' ')
+ isInAsmBlock = true;
+ else
+ isInAsmOneLine = true;
+ }
+ }
+
+ // append the entire name for all others
+ string name = getCurrentWord(line, i);
+ outBuffer.append(name.substr(1));
+ i += name.length() - 1;
+ continue;
+ }
+
+ // Handle operators
+
+ bool isPotentialOperator = isCharPotentialOperator(ch);
+
+ if (isPotentialOperator)
+ {
+ // Check if an operator has been reached.
+ const string *foundAssignmentOp = findOperator(line, i, assignmentOperators);
+ const string *foundNonAssignmentOp = findOperator(line, i, nonAssignmentOperators);
+
+ // Since findHeader's boundry checking was not used above, it is possible
+ // that both an assignment op and a non-assignment op where found,
+ // e.g. '>>' and '>>='. If this is the case, treat the LONGER one as the
+ // found operator.
+ if (foundAssignmentOp != NULL && foundNonAssignmentOp != NULL)
+ {
+ if (foundAssignmentOp->length() < foundNonAssignmentOp->length())
+ foundAssignmentOp = NULL;
+ else
+ foundNonAssignmentOp = NULL;
+ }
+
+ if (foundNonAssignmentOp != NULL)
+ {
+ if (foundNonAssignmentOp->length() > 1)
+ {
+ outBuffer.append(foundNonAssignmentOp->substr(1));
+ i += foundNonAssignmentOp->length() - 1;
+ }
+
+ // For C++ input/output, operator<< and >> should be
+ // aligned, if we are not in a statement already and
+ // also not in the "operator<<(...)" header line
+ if (!isInOperator
+ && inStatementIndentStack->empty()
+ && isCStyle()
+ && (foundNonAssignmentOp == &AS_GR_GR ||
+ foundNonAssignmentOp == &AS_LS_LS))
+ {
+ // this will be true if the line begins with the operator
+ if (i < 2 && spaceTabCount == 0)
+ spaceTabCount += 2 * indentLength;
+ // align to the beginning column of the operator
+ registerInStatementIndent(line, i - foundNonAssignmentOp->length(), spaceTabCount, tabIncrementIn, 0, false);
+ }
+ }
+
+ else if (foundAssignmentOp != NULL)
+ {
+ if (foundAssignmentOp->length() > 1)
+ {
+ outBuffer.append(foundAssignmentOp->substr(1));
+ i += foundAssignmentOp->length() - 1;
+ }
+
+ if (!isInOperator && !isInTemplate && !isNonInStatementArray)
+ {
+ // if multiple assignments, align on the previous word
+ if (foundAssignmentOp == &AS_ASSIGN
+ && prevNonSpaceCh != ']' // an array
+ && statementEndsWithComma(line, i))
+ {
+ if (!haveAssignmentThisLine) // only one assignment indent per line
+ {
+ // register indent at previous word
+ haveAssignmentThisLine = true;
+ int prevWordIndex = getInStatementIndentAssign(line, i);
+ int inStatementIndent = prevWordIndex + spaceTabCount + tabIncrementIn;
+ inStatementIndentStack->push_back(inStatementIndent);
+ }
+ }
+ else
+ registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, false);
+
+ isInStatement = true;
+ }
+ }
+ }
+ } // end of for loop * end of for loop * end of for loop * end of for loop * end of for loop *
+
+ // handle special cases of unindentation:
+
+ /*
+ * if '{' doesn't follow an immediately previous '{' in the headerStack
+ * (but rather another header such as "for" or "if", then unindent it
+ * by one indentation relative to its block.
+ */
+
+ if (!lineStartsInComment
+ && !blockIndent
+ && outBuffer.length() > 0
+ && outBuffer[0] == '{'
+ && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum == lineClosingBlocksNum)
+ && !(headerStack->size() > 1 && (*headerStack)[headerStack->size()-2] == &AS_OPEN_BRACKET)
+ && shouldIndentBrackettedLine)
+ --tabCount;
+
+ // must check one less in headerStack if more than one header on a line (allow-addins)...
+ else if (!lineStartsInComment
+ && (int) headerStack->size() > iPrelim + 1
+ && !blockIndent
+ && outBuffer.length() > 0
+ && outBuffer[0] == '{'
+ && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum == lineClosingBlocksNum)
+ && !(headerStack->size() > 2 && (*headerStack)[headerStack->size()-3] == &AS_OPEN_BRACKET)
+ && shouldIndentBrackettedLine)
+ --tabCount;
+
+ // unindent a closing bracket...
+ else if (!lineStartsInComment
+ && outBuffer.length() > 0
+ && outBuffer[0] == '}'
+ && shouldIndentBrackettedLine)
+ --tabCount;
+
+ // correctly indent one-line-blocks...
+ else if (!lineStartsInComment
+ && outBuffer.length() > 0
+ && lineOpeningBlocksNum > 0
+ && lineOpeningBlocksNum == lineClosingBlocksNum
+ && previousLineProbationTab)
+ --tabCount; //lineOpeningBlocksNum - (blockIndent ? 1 : 0);
+
+ // correctly indent class continuation lines...
+ else if (!lineStartsInComment
+ && !lineOpensComment
+ && isInClassHeaderTab
+ && !blockIndent
+ && outBuffer.length() > 0
+ && lineOpeningBlocksNum == 0
+ && lineOpeningBlocksNum == lineClosingBlocksNum
+ && (headerStack->size() > 0 && headerStack->back() == &AS_CLASS))
+ --tabCount;
+
+ if (tabCount < 0)
+ tabCount = 0;
+
+ // take care of extra bracket indentatation option...
+ if (!lineStartsInComment
+ && bracketIndent
+ && shouldIndentBrackettedLine
+ && outBuffer.length() > 0
+ && (outBuffer[0] == '{' || outBuffer[0] == '}'))
+ tabCount++;
+
+ if (isInDefine)
+ {
+ if (outBuffer[0] == '#')
+ {
+ string preproc = trim(string(outBuffer.c_str() + 1));
+ if (preproc.compare(0, 6, "define") == 0)
+ {
+ if (!inStatementIndentStack->empty()
+ && inStatementIndentStack->back() > 0)
+ {
+ defineTabCount = tabCount;
+ }
+ else
+ {
+ defineTabCount = tabCount - 1;
+ tabCount--;
+ }
+ }
+ }
+
+ tabCount -= defineTabCount;
+ }
+
+ if (tabCount < 0)
+ tabCount = 0;
+ if (lineCommentNoBeautify || blockCommentNoBeautify || isInQuoteContinuation)
+ tabCount = spaceTabCount = 0;
+
+ // finally, insert indentations into begining of line
+
+ if (shouldForceTabIndentation)
+ {
+ tabCount += spaceTabCount / indentLength;
+ spaceTabCount = spaceTabCount % indentLength;
+ }
+
+ outBuffer = preLineWS(spaceTabCount, tabCount) + outBuffer;
+
+ prevFinalLineSpaceTabCount = spaceTabCount;
+ prevFinalLineTabCount = tabCount;
+
+ if (lastLineHeader != NULL)
+ previousLastLineHeader = lastLineHeader;
+
+ return outBuffer;
+}
+
+
+string ASBeautifier::preLineWS(int spaceTabCount, int tabCount)
+{
+ string ws;
+
+ for (int i = 0; i < tabCount; i++)
+ ws += indentString;
+
+ while ((spaceTabCount--) > 0)
+ ws += string(" ");
+
+ return ws;
+
+}
+
+bool ASBeautifier::isClassAccessModifier(string& line) const
+{
+ size_t firstChar = line.find_first_not_of(" \t");
+ if (firstChar == string::npos)
+ return false;
+ // bypass a colon
+ if (line[firstChar] == ':')
+ {
+ firstChar = line.find_first_not_of(" \t");
+ if (firstChar == string::npos)
+ return false;
+ }
+ if (line.compare(firstChar, 7, "public ") == 0
+ || line.compare(firstChar, 8, "private ") == 0
+ || line.compare(firstChar, 10, "protected ") == 0)
+ return true;
+ return false;
+}
+
+/**
+ * register an in-statement indent.
+ */
+void ASBeautifier::registerInStatementIndent(const string &line, int i, int spaceTabCount,
+ int tabIncrementIn, int minIndent, bool updateParenStack)
+{
+ int inStatementIndent;
+ int remainingCharNum = line.length() - i;
+ int nextNonWSChar = getNextProgramCharDistance(line, i);
+
+ // if indent is around the last char in the line, indent instead one indent from the previous indent
+ if (nextNonWSChar == remainingCharNum)
+ {
+ int previousIndent = spaceTabCount;
+ if (!inStatementIndentStack->empty())
+ previousIndent = inStatementIndentStack->back();
+ int currIndent = /*2*/ indentLength + previousIndent;
+ if (currIndent > maxInStatementIndent
+ && line[i] != '{')
+ currIndent = indentLength * 2 + spaceTabCount;
+ inStatementIndentStack->push_back(currIndent);
+ if (updateParenStack)
+ parenIndentStack->push_back(previousIndent);
+ return;
+ }
+
+ if (updateParenStack)
+ parenIndentStack->push_back(i + spaceTabCount - horstmannIndentInStatement);
+
+ int tabIncrement = tabIncrementIn;
+
+ // check for following tabs
+ for (int j = i + 1; j < (i + nextNonWSChar); j++)
+ {
+ if (line[j] == '\t')
+ tabIncrement += convertTabToSpaces(j, tabIncrement);
+ }
+
+ inStatementIndent = i + nextNonWSChar + spaceTabCount + tabIncrement;
+
+ // check for run-in statement
+ if (i > 0 && line[0] == '{')
+ inStatementIndent -= indentLength;
+
+// if (i + nextNonWSChar < minIndent)
+// inStatementIndent = minIndent + spaceTabCount;
+
+ if (inStatementIndent < minIndent)
+ inStatementIndent = minIndent + spaceTabCount;
+
+// if (i + nextNonWSChar > maxInStatementIndent)
+// inStatementIndent = indentLength * 2 + spaceTabCount;
+
+ if (inStatementIndent > maxInStatementIndent)
+ inStatementIndent = indentLength * 2 + spaceTabCount;
+
+ if (!inStatementIndentStack->empty() &&
+ inStatementIndent < inStatementIndentStack->back())
+ inStatementIndent = inStatementIndentStack->back();
+
+ // the block opener is not indented for a NonInStatementArray
+ if (isNonInStatementArray && !bracketBlockStateStack->empty() && bracketBlockStateStack->back())
+ inStatementIndent = 0;
+
+ inStatementIndentStack->push_back(inStatementIndent);
+}
+
+/**
+ * get distance to the next non-white space, non-comment character in the line.
+ * if no such character exists, return the length remaining to the end of the line.
+ */
+int ASBeautifier::getNextProgramCharDistance(const string &line, int i) const
+{
+ bool inComment = false;
+ int remainingCharNum = line.length() - i;
+ int charDistance;
+ char ch;
+
+ for (charDistance = 1; charDistance < remainingCharNum; charDistance++)
+ {
+ ch = line[i + charDistance];
+ if (inComment)
+ {
+ if (line.compare(i + charDistance, 2, "*/") == 0)
+ {
+ charDistance++;
+ inComment = false;
+ }
+ continue;
+ }
+ else if (isWhiteSpace(ch))
+ continue;
+ else if (ch == '/')
+ {
+ if (line.compare(i + charDistance, 2, "//") == 0)
+ return remainingCharNum;
+ else if (line.compare(i + charDistance, 2, "/*") == 0)
+ {
+ charDistance++;
+ inComment = true;
+ }
+ }
+ else
+ return charDistance;
+ }
+
+ return charDistance;
+}
+
+// check if a specific line position contains a header.
+const string* ASBeautifier::findHeader(const string &line, int i,
+ const vector<const string*>* possibleHeaders) const
+{
+ assert(isCharPotentialHeader(line, i));
+ // check the word
+ size_t maxHeaders = possibleHeaders->size();
+ for (size_t p = 0; p < maxHeaders; p++)
+ {
+ const string* header = (*possibleHeaders)[p];
+ const size_t wordEnd = i + header->length();
+ if (wordEnd > line.length())
+ continue;
+ int result = (line.compare(i, header->length(), *header));
+ if (result > 0)
+ continue;
+ if (result < 0)
+ break;
+ // check that this is not part of a longer word
+ if (wordEnd == line.length())
+ return header;
+ if (isLegalNameChar(line[wordEnd]))
+ continue;
+ // is not a header if part of a definition
+ const char peekChar = peekNextChar(line, wordEnd - 1);
+ if (peekChar == ',' || peekChar == ')')
+ break;
+ return header;
+ }
+ return NULL;
+}
+
+// check if a specific line position contains an operator.
+const string* ASBeautifier::findOperator(const string &line, int i,
+ const vector<const string*>* possibleOperators) const
+{
+ assert(isCharPotentialOperator(line[i]));
+ // find the operator in the vector
+ // the vector contains the LONGEST operators first
+ // must loop thru the entire vector
+ size_t maxOperators = possibleOperators->size();
+ for (size_t p = 0; p < maxOperators; p++)
+ {
+ const size_t wordEnd = i + (*(*possibleOperators)[p]).length();
+ if (wordEnd > line.length())
+ continue;
+ if (line.compare(i, (*(*possibleOperators)[p]).length(), *(*possibleOperators)[p]) == 0)
+ return (*possibleOperators)[p];
+ }
+ return NULL;
+}
+
+/**
+ * find the index number of a string element in a container of strings
+ *
+ * @return the index number of element in the container. -1 if element not found.
+ * @param container a vector of strings.
+ * @param element the element to find .
+ */
+int ASBeautifier::indexOf(vector<const string*> &container, const string *element)
+{
+ vector<const string*>::const_iterator where;
+
+ where = find(container.begin(), container.end(), element);
+ if (where == container.end())
+ return -1;
+ else
+ return (int) (where - container.begin());
+}
+
+/**
+ * convert tabs to spaces.
+ * i is the position of the character to convert to spaces.
+ * tabIncrementIn is the increment that must be added for tab indent characters
+ * to get the correct column for the current tab.
+ */
+int ASBeautifier::convertTabToSpaces(int i, int tabIncrementIn) const
+{
+ int tabToSpacesAdjustment = indentLength - 1 - ((tabIncrementIn + i) % indentLength);
+ return tabToSpacesAdjustment;
+}
+
+/**
+ * trim removes the white space surrounding a line.
+ *
+ * @return the trimmed line.
+ * @param str the line to trim.
+ */
+string ASBeautifier::trim(const string &str)
+{
+
+ int start = 0;
+ int end = str.length() - 1;
+
+ while (start < end && isWhiteSpace(str[start]))
+ start++;
+
+ while (start <= end && isWhiteSpace(str[end]))
+ end--;
+
+ string returnStr(str, start, end + 1 - start);
+ return returnStr;
+}
+
+/**
+ * Copy tempStacks for the copy constructor.
+ * The value of the vectors must also be copied.
+ */
+vector<vector<const string*>*>* ASBeautifier::copyTempStacks(const ASBeautifier &other) const
+{
+ vector<vector<const string*>*> *tempStacksNew = new vector<vector<const string*>*>;
+ vector<vector<const string*>*>::iterator iter;
+ for (iter = other.tempStacks->begin();
+ iter != other.tempStacks->end();
+ ++iter)
+ {
+ vector<const string*> *newVec = new vector<const string*>;
+ *newVec = **iter;
+ tempStacksNew->push_back(newVec);
+ }
+ return tempStacksNew;
+}
+
+/**
+ * delete a static member vector to eliminate memory leak reporting for the vector
+ */
+void ASBeautifier::deleteStaticVectors()
+{
+ beautifierFileType = 9; // reset to an invalid type
+ deleteVector(headers);
+ deleteVector(nonParenHeaders);
+ deleteVector(preBlockStatements);
+ deleteVector(assignmentOperators);
+ deleteVector(nonAssignmentOperators);
+ deleteVector(indentableHeaders);
+}
+
+/**
+ * delete a vector object
+ * T is the type of vector
+ * used for all vectors except tempStacks
+ */
+template<typename T>
+void ASBeautifier::deleteContainer(T &container)
+{
+ if (container != NULL)
+ {
+ container->clear();
+ delete (container);
+ container = NULL;
+ }
+}
+
+/**
+ * Delete the tempStacks vector object.
+ * The tempStacks is a vector of pointers to strings allocated with
+ * the 'new' operator.
+ * Therefore the strings have to be deleted in addition to the
+ * tempStacks entries.
+ */
+void ASBeautifier::deleteContainer(vector<vector<const string*>*>* &container)
+{
+ if (container != NULL)
+ {
+ vector<vector<const string*>*>::iterator iter = container->begin();
+ for (; iter != container->end(); iter++)
+ delete *iter;
+ container->clear();
+ delete (container);
+ container = NULL;
+ }
+}
+
+/**
+ * delete a vector<const string*>* object
+ */
+void ASBeautifier::deleteVector(vector<const string*>*& container)
+{
+ assert(container != NULL);
+ delete container;
+ container = NULL;
+}
+
+/**
+ * initialize a vector object
+ * T is the type of vector
+ * used for all vectors
+ */
+template<typename T>
+void ASBeautifier::initContainer(T &container, T value)
+{
+ // since the ASFormatter object is never deleted,
+ // the existing vectors must be deleted before creating new ones
+ if (container != NULL )
+ deleteContainer(container);
+ container = value;
+}
+
+/**
+ * initialize a vector<const string*>* object
+ */
+void ASBeautifier::initVector(vector<const string*>*& container)
+{
+ assert(container == NULL);
+ container = new vector<const string*>;
+}
+
+/**
+ * Determine if an assignment statement ends with a comma
+ * that is not in a function argument. It ends with a
+ * comma if a comma is the last char on the line.
+ *
+ * @return true if line ends with a comma, otherwise false.
+ */
+bool ASBeautifier::statementEndsWithComma(string &line, int index)
+{
+ assert(line[index] == '=');
+
+ bool isInComment = false;
+ bool isInQuote = false;
+ int parenCount = 0;
+ size_t lineLength = line.length();
+ size_t i = 0;
+ char quoteChar = ' ';
+
+ for (i = index + 1; i < lineLength; ++i)
+ {
+ char ch = line[i];
+
+ if (isInComment)
+ {
+ if (line.compare(i, 2, "*/") == 0)
+ {
+ isInComment = false;
+ ++i;
+ }
+ continue;
+ }
+
+ if (ch == '\\')
+ {
+ ++i;
+ continue;
+ }
+
+ if (isInQuote)
+ {
+ if (ch == quoteChar)
+ isInQuote = false;
+ continue;
+ }
+
+ if (ch == '"' || ch == '\'')
+ {
+ isInQuote = true;
+ quoteChar = ch;
+ continue;
+ }
+
+ if (line.compare(i, 2, "//") == 0)
+ break;
+
+ if (line.compare(i, 2, "/*") == 0)
+ {
+ if (isLineEndComment(line, i))
+ break;
+ else
+ {
+ isInComment = true;
+ ++i;
+ continue;
+ }
+ }
+
+ if (ch == '(')
+ parenCount++;
+ if (ch == ')')
+ parenCount--;
+ }
+ if (isInComment
+ || isInQuote
+ || parenCount > 0)
+ return false;
+
+ size_t lastChar = line.find_last_not_of(" \t", i - 1);
+
+ if (lastChar == string::npos || line[lastChar] != ',')
+ return false;
+
+ return true;
+}
+
+/**
+ * check if current comment is a line-end comment
+ *
+ * @return is before a line-end comment.
+ */
+bool ASBeautifier::isLineEndComment(string& line, int startPos) const
+{
+ assert(line.compare(startPos, 2, "/*") == 0);
+
+ // comment must be closed on this line with nothing after it
+ size_t endNum = line.find("*/", startPos + 2);
+ if (endNum != string::npos)
+ {
+ size_t nextChar = line.find_first_not_of(" \t", endNum + 2);
+ if (nextChar == string::npos)
+ return true;
+ }
+ return false;
+}
+
+/**
+ * get the previous word index for an assignment operator
+ *
+ * @return is the index to the previous word (the in statement indent).
+ */
+int ASBeautifier::getInStatementIndentAssign(const string& line, size_t currPos) const
+{
+ assert(line[currPos] == '=');
+
+ if (currPos == 0)
+ return 0;
+
+ // get the last legal word (may be a number)
+ size_t end = line.find_last_not_of(" \t", currPos-1);
+ if (end == string::npos || !isLegalNameChar(line[end]))
+ return 0;
+
+ int start; // start of the previous word
+ for (start = end; start > -1; start--)
+ {
+ if (!isLegalNameChar(line[start]) || line[start] == '.')
+ break;
+ }
+ start++;
+
+ return start;
+}
+
+/**
+ * get the instatement indent for a comma
+ *
+ * @return is the indent to the second word on the line (the in statement indent).
+ */
+int ASBeautifier::getInStatementIndentComma(const string& line, size_t currPos) const
+{
+ assert(line[currPos] == ',');
+
+ if (currPos == 0)
+ return 0;
+
+ // get first word on a line
+ size_t indent = line.find_first_not_of(" \t");
+ if (indent == string::npos || !isLegalNameChar(line[indent]))
+ return 0;
+
+ // bypass first word
+ for (; indent < currPos; indent++)
+ {
+ if (!isLegalNameChar(line[indent]))
+ break;
+ }
+ indent++;
+ if (indent >= currPos)
+ return 0;
+
+ // point to second word or assignment operator
+ indent = line.find_last_not_of(" \t", indent);
+ if (indent == string::npos || indent >= currPos)
+ return 0;
+
+ return indent;
+}
+
+
+} // end namespace astyle
+
diff --git a/support/highlight/src/core/astyle/ASEnhancer.cpp b/support/highlight/src/core/astyle/ASEnhancer.cpp
new file mode 100644
index 0000000000..7615601431
--- /dev/null
+++ b/support/highlight/src/core/astyle/ASEnhancer.cpp
@@ -0,0 +1,582 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Copyright (C) 2006-2010 by Jim Pattee <jimp03@email.com>
+ * Copyright (C) 1998-2002 by Tal Davidson
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>
+ *
+ * This file is a part of Artistic Style - an indentation and
+ * reformatting tool for C, C++, C# and Java source files.
+ * <http://astyle.sourceforge.net>
+ *
+ * Artistic Style is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Artistic Style is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Artistic Style. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+#include "astyle.h"
+
+
+namespace astyle
+{
+
+// ---------------------------- functions for ASEnhancer Class -------------------------------------
+
+/**
+ * ASEnhancer constructor
+ */
+ASEnhancer::ASEnhancer()
+{
+ // the following prevents warning messages with cppcheck
+ // it will NOT compile if activated
+// init();
+}
+
+/**
+ * Destructor of ASEnhancer
+ */
+ASEnhancer::~ASEnhancer()
+{
+}
+
+/**
+ * initialize the ASEnhancer.
+ *
+ * init() is called each time an ASFormatter object is initialized.
+ */
+void ASEnhancer::init(int fileType,
+ int _indentLength,
+ string _indentString,
+ bool _caseIndent,
+ bool _emptyLineFill)
+{
+ // formatting variables from ASFormatter and ASBeautifier
+ ASBase::init(fileType);
+ indentLength = _indentLength;
+ if (_indentString == "\t")
+ useTabs = true;
+ else
+ useTabs = false;
+
+ caseIndent = _caseIndent;
+ emptyLineFill = _emptyLineFill;
+ quoteChar = '\'';
+
+ // unindent variables
+ lineNumber = 0;
+ bracketCount = 0;
+ isInComment = false;
+ isInQuote = false;
+ switchDepth = 0;
+ lookingForCaseBracket = false;
+ unindentNextLine = false;
+
+ // switch struct and vector
+ sw.switchBracketCount = 0;
+ sw.unindentDepth = 0;
+ sw.unindentCase = false;
+ swVector.clear();
+
+ // other variables
+ nextLineIsEventIndent = false;
+ isInEventTable = false;
+ nextLineIsDeclareIndent = false;
+ isInDeclareSection = false;
+}
+
+/**
+ * additional formatting for line of source code.
+ * every line of source code in a source code file should be sent
+ * one after the other to this function.
+ * indents event tables
+ * unindents the case blocks
+ *
+ * @param line the original formatted line will be updated if necessary.
+ */
+void ASEnhancer::enhance(string &line, bool isInSQL)
+{
+ bool isSpecialChar = false; // is a backslash escape character
+
+ lineNumber++;
+
+ // check for beginning of event table
+ if (nextLineIsEventIndent)
+ {
+ isInEventTable = true;
+ nextLineIsEventIndent = false;
+ }
+
+ // check for beginning of SQL declare section
+ if (nextLineIsDeclareIndent)
+ {
+ isInDeclareSection = true;
+ nextLineIsDeclareIndent = false;
+ }
+
+ if (line.length() == 0
+ && ! isInEventTable
+ && ! isInDeclareSection
+ && ! emptyLineFill)
+ return;
+
+ // test for unindent on attached brackets
+ if (unindentNextLine)
+ {
+ sw.unindentDepth++;
+ sw.unindentCase = true;
+ unindentNextLine = false;
+ }
+
+ // parse characters in the current line.
+
+ for (size_t i = 0; i < line.length(); i++)
+ {
+ char ch = line[i];
+
+ // bypass whitespace
+ if (isWhiteSpace(ch))
+ continue;
+
+ // handle special characters (i.e. backslash+character such as \n, \t, ...)
+ if (isSpecialChar)
+ {
+ isSpecialChar = false;
+ continue;
+ }
+ if (!(isInComment) && line.compare(i, 2, "\\\\") == 0)
+ {
+ i++;
+ continue;
+ }
+ if (!(isInComment) && ch == '\\')
+ {
+ isSpecialChar = true;
+ continue;
+ }
+
+ // handle quotes (such as 'x' and "Hello Dolly")
+ if (!isInComment && (ch == '"' || ch == '\''))
+ {
+ if (!isInQuote)
+ {
+ quoteChar = ch;
+ isInQuote = true;
+ }
+ else if (quoteChar == ch)
+ {
+ isInQuote = false;
+ continue;
+ }
+ }
+
+ if (isInQuote)
+ continue;
+
+ // handle comments
+
+ if (!(isInComment) && line.compare(i, 2, "//") == 0)
+ {
+ // check for windows line markers
+ if (line.compare(i + 2, 1, "\xf0") > 0)
+ lineNumber--;
+ break; // finished with the line
+ }
+ else if (!(isInComment) && line.compare(i, 2, "/*") == 0)
+ {
+ isInComment = true;
+ i++;
+ continue;
+ }
+ else if ((isInComment) && line.compare(i, 2, "*/") == 0)
+ {
+ isInComment = false;
+ i++;
+ continue;
+ }
+
+ if (isInComment)
+ continue;
+
+ // if we have reached this far then we are NOT in a comment or string of special characters
+
+ if (line[i] == '{')
+ bracketCount++;
+
+ if (line[i] == '}')
+ bracketCount--;
+
+ bool isPotentialKeyword = isCharPotentialHeader(line, i);
+
+ // ---------------- process event tables --------------------------------------
+
+ if (isPotentialKeyword)
+ {
+ if (findKeyword(line, i, "BEGIN_EVENT_TABLE")
+ || findKeyword(line, i, "BEGIN_MESSAGE_MAP"))
+ {
+ nextLineIsEventIndent = true;
+ break;
+ }
+
+ if (findKeyword(line, i, "END_EVENT_TABLE")
+ || findKeyword(line, i, "END_MESSAGE_MAP"))
+ {
+ isInEventTable = false;
+ break;
+ }
+ }
+
+ // ---------------- process SQL -----------------------------------------------
+
+ if (isInSQL)
+ {
+ if (isBeginDeclareSectionSQL(line, i))
+ nextLineIsDeclareIndent = true;
+ if (isEndDeclareSectionSQL(line, i))
+ isInDeclareSection = false;
+ break;
+ }
+
+ // ---------------- process switch statements ---------------------------------
+
+ if (isPotentialKeyword && findKeyword(line, i, "switch"))
+ {
+ switchDepth++;
+ swVector.push_back(sw); // save current variables
+ sw.switchBracketCount = 0;
+ sw.unindentCase = false; // don't clear case until end of switch
+ i += 5; // bypass switch statement
+ continue;
+ }
+
+ // just want unindented switch statements from this point
+
+ if (caseIndent || switchDepth == 0)
+ {
+ // bypass the entire word
+ if (isPotentialKeyword)
+ {
+ string name = getCurrentWord(line, i);
+ i += name.length() - 1;
+ }
+ continue;
+ }
+
+ i = processSwitchBlock(line, i);
+
+ } // end of for loop * end of for loop * end of for loop * end of for loop
+
+ if (isInEventTable || isInDeclareSection)
+ {
+ if (line[0] != '#')
+ indentLine(line, 1);
+ }
+
+ if (sw.unindentDepth > 0)
+ unindentLine(line, sw.unindentDepth);
+}
+
+/**
+ * find the colon following a 'case' statement
+ *
+ * @param line a reference to the line.
+ * @param i the line index of the case statement.
+ * @return the line index of the colon.
+ */
+size_t ASEnhancer::findCaseColon(string &line, size_t caseIndex) const
+{
+ size_t i = caseIndex;
+ bool isInQuote = false;
+ char quoteChar = ' ';
+ for (; i < line.length(); i++)
+ {
+ if (isInQuote)
+ {
+ if (line[i] == '\\')
+ {
+ i++;
+ continue;
+ }
+ else if (line[i] == quoteChar) // check ending quote
+ {
+ isInQuote = false;
+ quoteChar = ' ';
+ continue;
+ }
+ else
+ {
+ continue; // must close quote before continuing
+ }
+ }
+ if (line[i] == '\'' || line[i] == '\"') // check opening quote
+ {
+ isInQuote = true;
+ quoteChar = line[i];
+ continue;
+ }
+ if (line[i] == ':')
+ {
+ if ((i + 1 < line.length()) && (line[i + 1] == ':'))
+ i++; // bypass scope resolution operator
+ else
+ break; // found it
+ }
+ }
+ return i;
+}
+
+/**
+ * indent a line by a given number of tabsets
+ * by inserting leading whitespace to the line argument.
+ *
+ * @param line a reference to the line to indent.
+ * @param unindent the number of tabsets to insert.
+ * @return the number of characters inserted.
+ */
+int ASEnhancer::indentLine(string &line, int indent) const
+{
+ if (line.length() == 0
+ && ! emptyLineFill)
+ return 0;
+
+ size_t charsToInsert; // number of chars to insert
+
+ if (useTabs) // if formatted with tabs
+ {
+ charsToInsert = indent; // tabs to insert
+ line.insert((size_t) 0, charsToInsert, '\t'); // insert the tabs
+ }
+ else
+ {
+ charsToInsert = indent * indentLength; // compute chars to insert
+ line.insert((size_t)0, charsToInsert, ' '); // insert the spaces
+ }
+
+ return charsToInsert;
+}
+
+/**
+ * check for SQL "BEGIN DECLARE SECTION".
+ * must compare case insensitive and allow any spacing between words.
+ *
+ * @param line a reference to the line to indent.
+ * @param index the current line index.
+ * @return true if a hit.
+ */
+bool ASEnhancer::isBeginDeclareSectionSQL(string &line, size_t index) const
+{
+ string word;
+ size_t hits = 0;
+ size_t i;
+ for (i = index; i < line.length(); i++)
+ {
+ i = line.find_first_not_of(" \t", i);
+ if (i == string::npos)
+ return false;
+ if (line[i] == ';')
+ break;
+ if (!isCharPotentialHeader(line, i))
+ continue;
+ word = getCurrentWord(line, i);
+ for (size_t j = 0; j < word.length(); j++)
+ word[j] = (char) toupper(word[j]);
+ if (word == "EXEC" || word == "SQL")
+ {
+ i += word.length() - 1;
+ continue;
+ }
+ if (word == "DECLARE" || word == "SECTION")
+ {
+ hits++;
+ i += word.length() - 1;
+ continue;
+ }
+ if (word == "BEGIN")
+ {
+ hits++;
+ i += word.length() - 1;
+ continue;
+ }
+ return false;
+ }
+ if (hits == 3)
+ return true;
+ return false;
+}
+
+/**
+ * check for SQL "END DECLARE SECTION".
+ * must compare case insensitive and allow any spacing between words.
+ *
+ * @param line a reference to the line to indent.
+ * @param index the current line index.
+ * @return true if a hit.
+ */
+bool ASEnhancer::isEndDeclareSectionSQL(string &line, size_t index) const
+{
+ string word;
+ size_t hits = 0;
+ size_t i;
+ for (i = index; i < line.length(); i++)
+ {
+ i = line.find_first_not_of(" \t", i);
+ if (i == string::npos)
+ return false;
+ if (line[i] == ';')
+ break;
+ if (!isCharPotentialHeader(line, i))
+ continue;
+ word = getCurrentWord(line, i);
+ for (size_t j = 0; j < word.length(); j++)
+ word[j] = (char) toupper(word[j]);
+ if (word == "EXEC" || word == "SQL")
+ {
+ i += word.length() - 1;
+ continue;
+ }
+ if (word == "DECLARE" || word == "SECTION")
+ {
+ hits++;
+ i += word.length() - 1;
+ continue;
+ }
+ if (word == "END")
+ {
+ hits++;
+ i += word.length() - 1;
+ continue;
+ }
+ return false;
+ }
+ if (hits == 3)
+ return true;
+ return false;
+}
+
+/**
+ * process the character at the current index in a switch block.
+ *
+ * @param line a reference to the line to indent.
+ * @param index the current line index.
+ * @return the new line index.
+ */
+size_t ASEnhancer::processSwitchBlock(string &line, size_t index)
+{
+ size_t i = index;
+ bool isPotentialKeyword = isCharPotentialHeader(line, i);
+
+ if (line[i] == '{')
+ {
+ sw.switchBracketCount++;
+ if (lookingForCaseBracket) // if 1st after case statement
+ {
+ sw.unindentCase = true; // unindenting this case
+ sw.unindentDepth++;
+ lookingForCaseBracket = false; // not looking now
+ }
+ return i;
+ }
+ lookingForCaseBracket = false; // no opening bracket, don't indent
+
+ if (line[i] == '}') // if close bracket
+ {
+ sw.switchBracketCount--;
+ if (sw.switchBracketCount == 0) // if end of switch statement
+ {
+ switchDepth--; // one less switch
+ sw = swVector.back(); // restore sw struct
+ swVector.pop_back(); // remove last entry from stack
+ }
+ return i;
+ }
+
+ if (isPotentialKeyword
+ && (findKeyword(line, i, "case") || findKeyword(line, i, "default")))
+ {
+ if (sw.unindentCase) // if unindented last case
+ {
+ sw.unindentCase = false; // stop unindenting previous case
+ sw.unindentDepth--; // reduce depth
+ }
+
+ i = findCaseColon(line, i);
+
+ i++;
+ for (; i < line.length(); i++) // bypass whitespace
+ {
+ if (!isWhiteSpace(line[i]))
+ break;
+ }
+ if (i < line.length())
+ {
+ if (line[i] == '{')
+ {
+ sw.switchBracketCount++;
+ unindentNextLine = true;
+ return i;
+ }
+ }
+ lookingForCaseBracket = true; // bracket must be on next line
+ i--; // need to check for comments
+ return i;
+ }
+ if (isPotentialKeyword)
+ {
+ string name = getCurrentWord(line, i); // bypass the entire name
+ i += name.length() - 1;
+ }
+ return i;
+}
+
+/**
+ * unindent a line by a given number of tabsets
+ * by erasing the leading whitespace from the line argument.
+ *
+ * @param line a reference to the line to unindent.
+ * @param unindent the number of tabsets to erase.
+ * @return the number of characters erased.
+ */
+int ASEnhancer::unindentLine(string &line, int unindent) const
+{
+ size_t whitespace = line.find_first_not_of(" \t");
+
+ if (whitespace == string::npos) // if line is blank
+ whitespace = line.length(); // must remove padding, if any
+
+ if (whitespace == 0)
+ return 0;
+
+ size_t charsToErase; // number of chars to erase
+
+ if (useTabs) // if formatted with tabs
+ {
+ charsToErase = unindent; // tabs to erase
+ if (charsToErase <= whitespace) // if there is enough whitespace
+ line.erase(0, charsToErase); // erase the tabs
+ else
+ charsToErase = 0;
+ }
+ else
+ {
+ charsToErase = unindent * indentLength; // compute chars to erase
+ if (charsToErase <= whitespace) // if there is enough whitespace
+ line.erase(0, charsToErase); // erase the spaces
+ else
+ charsToErase = 0;
+ }
+
+ return charsToErase;
+}
+
+
+} // end namespace astyle
diff --git a/support/highlight/src/core/astyle/ASFormatter.cpp b/support/highlight/src/core/astyle/ASFormatter.cpp
new file mode 100644
index 0000000000..3617c325b0
--- /dev/null
+++ b/support/highlight/src/core/astyle/ASFormatter.cpp
@@ -0,0 +1,4520 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Copyright (C) 2006-2010 by Jim Pattee <jimp03@email.com>
+ * Copyright (C) 1998-2002 by Tal Davidson
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>
+ *
+ * This file is a part of Artistic Style - an indentation and
+ * reformatting tool for C, C++, C# and Java source files.
+ * <http://astyle.sourceforge.net>
+ *
+ * Artistic Style is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Artistic Style is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Artistic Style. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+#include "astyle.h"
+
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+
+
+namespace astyle
+{
+// static member variables
+int ASFormatter::formatterFileType = 9; // initialized with an invalid type
+vector<const string*>* ASFormatter::headers = NULL;
+vector<const string*>* ASFormatter::nonParenHeaders = NULL;
+vector<const string*>* ASFormatter::preDefinitionHeaders = NULL;
+vector<const string*>* ASFormatter::preCommandHeaders = NULL;
+vector<const string*>* ASFormatter::operators = NULL;
+vector<const string*>* ASFormatter::assignmentOperators = NULL;
+vector<const string*>* ASFormatter::castOperators = NULL;
+
+/**
+ * Constructor of ASFormatter
+ */
+ASFormatter::ASFormatter()
+{
+ sourceIterator = NULL;
+ enhancer = new ASEnhancer;
+ preBracketHeaderStack = NULL;
+ bracketTypeStack = NULL;
+ parenStack = NULL;
+ structStack = NULL;
+ lineCommentNoIndent = false;
+ formattingStyle = STYLE_NONE;
+ bracketFormatMode = NONE_MODE;
+ pointerAlignment = ALIGN_NONE;
+ lineEnd = LINEEND_DEFAULT;
+ shouldPadOperators = false;
+ shouldPadParensOutside = false;
+ shouldPadParensInside = false;
+ shouldPadHeader = false;
+ shouldUnPadParens = false;
+ shouldBreakOneLineBlocks = true;
+ shouldBreakOneLineStatements = true;
+ shouldConvertTabs = false;
+ shouldIndentCol1Comments = false;
+ shouldBreakBlocks = false;
+ shouldBreakClosingHeaderBlocks = false;
+ shouldBreakClosingHeaderBrackets = false;
+ shouldDeleteEmptyLines = false;
+ shouldBreakElseIfs = false;
+ shouldAddBrackets = false;
+ shouldAddOneLineBrackets = false;
+
+ // initialize ASFormatter static member vectors
+ formatterFileType = 9; // reset to an invalid type
+ initVector(headers);
+ initVector(nonParenHeaders);
+ initVector(preDefinitionHeaders);
+ initVector(preCommandHeaders);
+ initVector(operators);
+ initVector(assignmentOperators);
+ initVector(castOperators);
+
+ // the following prevents warning messages with cppcheck
+ // it will NOT compile if activated
+// init();
+}
+
+/**
+ * Destructor of ASFormatter
+ */
+ASFormatter::~ASFormatter()
+{
+ // delete ASFormatter stack vectors
+ deleteContainer(preBracketHeaderStack);
+ deleteContainer(bracketTypeStack);
+ deleteContainer(parenStack);
+ deleteContainer(structStack);
+
+ // delete static member vectors using swap to eliminate memory leak reporting
+ // delete ASFormatter static member vectors
+ formatterFileType = 9; // reset to an invalid type
+ deleteVector(headers);
+ deleteVector(nonParenHeaders);
+ deleteVector(preDefinitionHeaders);
+ deleteVector(preCommandHeaders);
+ deleteVector(operators);
+ deleteVector(assignmentOperators);
+ deleteVector(castOperators);
+
+ // delete ASBeautifier static member vectors
+ // must be done when the ASFormatter object is deleted (not ASBeautifier)
+ ASBeautifier::deleteStaticVectors();
+
+ delete enhancer;
+}
+
+/**
+ * initialize the ASFormatter.
+ *
+ * init() should be called every time a ASFormatter object is to start
+ * formatting a NEW source file.
+ * init() recieves a pointer to a ASSourceIterator object that will be
+ * used to iterate through the source code.
+ *
+ * @param sourceIterator a pointer to the ASSourceIterator or ASStreamIterator object.
+ */
+void ASFormatter::init(ASSourceIterator *si)
+{
+ buildLanguageVectors();
+ fixOptionVariableConflicts();
+
+ ASBeautifier::init(si);
+ enhancer->init(getFileType(),
+ getIndentLength(),
+ getIndentString(),
+ getCaseIndent(),
+ getEmptyLineFill());
+ sourceIterator = si;
+
+ initContainer(preBracketHeaderStack, new vector<const string*>);
+ initContainer(parenStack, new vector<int>);
+ initContainer(structStack, new vector<bool>);
+ parenStack->push_back(0); // parenStack must contain this default entry
+ initContainer(bracketTypeStack, new vector<BracketType>);
+ bracketTypeStack->push_back(NULL_TYPE);
+
+ currentHeader = NULL;
+ currentLine = "";
+ readyFormattedLine = "";
+ formattedLine = "";
+ currentChar = ' ';
+ previousChar = ' ';
+ previousCommandChar = ' ';
+ previousNonWSChar = ' ';
+ quoteChar = '"';
+ charNum = 0;
+ leadingSpaces = 0;
+ formattedLineCommentNum = 0;
+ preprocBracketTypeStackSize = 0;
+ spacePadNum = 0;
+ nextLineSpacePadNum = 0;
+ currentLineFirstBracketNum = string::npos;
+ previousReadyFormattedLineLength = string::npos;
+ templateDepth = 0;
+ traceLineNumber = 0;
+ horstmannIndentChars = 0;
+ tabIncrementIn = 0;
+ previousBracketType = NULL_TYPE;
+ previousOperator = NULL;
+
+ isVirgin = true;
+ isInLineComment = false;
+ isInComment = false;
+ noTrimCommentContinuation = false;
+ isInPreprocessor = false;
+ doesLineStartComment = false;
+ lineEndsInCommentOnly = false;
+ lineIsLineCommentOnly = false;
+ lineIsEmpty = false;
+ isImmediatelyPostCommentOnly = false;
+ isImmediatelyPostEmptyLine = false;
+ isInQuote = false;
+ isInVerbatimQuote = false;
+ haveLineContinuationChar = false;
+ isInQuoteContinuation = false;
+ isSpecialChar = false;
+ isNonParenHeader = false;
+ foundNamespaceHeader = false;
+ foundClassHeader = false;
+ foundStructHeader = false;
+ foundInterfaceHeader = false;
+ foundPreDefinitionHeader = false;
+ foundPreCommandHeader = false;
+ foundCastOperator = false;
+ foundQuestionMark = false;
+ isInLineBreak = false;
+ endOfCodeReached = false;
+ isInExecSQL = false;
+ isInAsm = false;
+ isInAsmOneLine = false;
+ isInAsmBlock = false;
+ isLineReady = false;
+ isPreviousBracketBlockRelated = false;
+ isInPotentialCalculation = false;
+ shouldReparseCurrentChar = false;
+ needHeaderOpeningBracket = false;
+ shouldBreakLineAtNextChar = false;
+ passedSemicolon = false;
+ passedColon = false;
+ clearNonInStatement = false;
+ isInTemplate = false;
+ isInBlParen = false;
+ isImmediatelyPostComment = false;
+ isImmediatelyPostLineComment = false;
+ isImmediatelyPostEmptyBlock = false;
+ isImmediatelyPostPreprocessor = false;
+ isImmediatelyPostReturn = false;
+ isImmediatelyPostOperator = false;
+ isCharImmediatelyPostReturn = false;
+ isCharImmediatelyPostOperator = false;
+ isCharImmediatelyPostComment = false;
+ isPreviousCharPostComment = false;
+ isCharImmediatelyPostLineComment = false;
+ isCharImmediatelyPostOpenBlock = false;
+ isCharImmediatelyPostCloseBlock = false;
+ isCharImmediatelyPostTemplate = false;
+ breakCurrentOneLineBlock = false;
+ isInHorstmannRunIn = false;
+ currentLineBeginsWithBracket = false;
+ isPrependPostBlockEmptyLineRequested = false;
+ isAppendPostBlockEmptyLineRequested = false;
+ prependEmptyLine = false;
+ appendOpeningBracket = false;
+ foundClosingHeader = false;
+ isImmediatelyPostHeader = false;
+ isInHeader = false;
+ isInCase = false;
+ isJavaStaticConstructor = false;
+}
+
+/**
+ * build vectors for each programing language
+ * depending on the file extension.
+ */
+void ASFormatter::buildLanguageVectors()
+{
+ if (getFileType() == formatterFileType) // don't build unless necessary
+ return;
+
+ formatterFileType = getFileType();
+
+ headers->clear();
+ nonParenHeaders->clear();
+ preDefinitionHeaders->clear();
+ preCommandHeaders->clear();
+ operators->clear();
+ assignmentOperators->clear();
+ castOperators->clear();
+
+ ASResource::buildHeaders(headers, getFileType());
+ ASResource::buildNonParenHeaders(nonParenHeaders, getFileType());
+ ASResource::buildPreDefinitionHeaders(preDefinitionHeaders, getFileType());
+ ASResource::buildPreCommandHeaders(preCommandHeaders, getFileType());
+ if (operators->size() == 0)
+ ASResource::buildOperators(operators);
+ if (assignmentOperators->size() == 0)
+ ASResource::buildAssignmentOperators(assignmentOperators);
+ if (castOperators->size() == 0)
+ ASResource::buildCastOperators(castOperators);
+}
+
+/**
+ * set the variables for each preefined style.
+ * this will override any previous settings.
+ */
+void ASFormatter::fixOptionVariableConflicts()
+{
+ if (formattingStyle == STYLE_ALLMAN)
+ {
+ setBracketFormatMode(BREAK_MODE);
+ setBlockIndent(false);
+ setBracketIndent(false);
+ }
+ else if (formattingStyle == STYLE_JAVA)
+ {
+ setBracketFormatMode(ATTACH_MODE);
+ setBlockIndent(false);
+ setBracketIndent(false);
+ }
+ else if (formattingStyle == STYLE_KandR)
+ {
+ setBracketFormatMode(LINUX_MODE);
+ setBlockIndent(false);
+ setBracketIndent(false);
+ }
+ else if (formattingStyle == STYLE_STROUSTRUP)
+ {
+ setBracketFormatMode(STROUSTRUP_MODE);
+ setBlockIndent(false);
+ setBracketIndent(false);
+ if (!getIndentManuallySet())
+ {
+ if (getIndentString() == "\t")
+ setTabIndentation(5, getForceTabIndentation());
+ else
+ setSpaceIndentation(5);
+ }
+ }
+ else if (formattingStyle == STYLE_WHITESMITH)
+ {
+ setBracketFormatMode(BREAK_MODE);
+ setBlockIndent(false);
+ setBracketIndent(true);
+ setClassIndent(true);
+ setSwitchIndent(true);
+ }
+ else if (formattingStyle == STYLE_BANNER)
+ {
+ setBracketFormatMode(ATTACH_MODE);
+ setBlockIndent(false);
+ setBracketIndent(true);
+ setClassIndent(true);
+ setSwitchIndent(true);
+ }
+ else if (formattingStyle == STYLE_GNU)
+ {
+ setBracketFormatMode(BREAK_MODE);
+ setBlockIndent(true);
+ setBracketIndent(false);
+ if (!getIndentManuallySet())
+ {
+ if (getIndentString() == "\t")
+ setTabIndentation(2, getForceTabIndentation());
+ else
+ setSpaceIndentation(2);
+ }
+ }
+ else if (formattingStyle == STYLE_LINUX)
+ {
+ setBracketFormatMode(LINUX_MODE);
+ setBlockIndent(false);
+ setBracketIndent(false);
+ if (!getIndentManuallySet())
+ {
+ if (getIndentString() == "\t")
+ setTabIndentation(8, getForceTabIndentation());
+ else
+ setSpaceIndentation(8);
+ }
+ if (!getMinConditionalManuallySet())
+ setMinConditionalIndentLength(getIndentLength() / 2);
+ }
+ else if (formattingStyle == STYLE_HORSTMANN)
+ {
+ setBracketFormatMode(HORSTMANN_MODE);
+ setBlockIndent(false);
+ setBracketIndent(false);
+ setSwitchIndent(true);
+ if (!getIndentManuallySet())
+ {
+ if (getIndentString() == "\t")
+ setTabIndentation(3, getForceTabIndentation());
+ else
+ setSpaceIndentation(3);
+ }
+ }
+ else if (formattingStyle == STYLE_1TBS)
+ {
+ setBracketFormatMode(LINUX_MODE);
+ setBlockIndent(false);
+ setBracketIndent(false);
+ setAddBracketsMode(true);
+ }
+
+ // add-one-line-brackets implies keep-one-line-blocks
+ if (shouldAddOneLineBrackets)
+ setBreakOneLineBlocksMode(false);
+ // cannot have both indent-blocks and indent-brackets, default to indent-blocks
+ if (getBlockIndent())
+ setBracketIndent(false);
+}
+
+/**
+ * get the next formatted line.
+ *
+ * @return formatted line.
+ */
+
+string ASFormatter::nextLine()
+{
+ const string *newHeader;
+ bool isInVirginLine = isVirgin;
+ isCharImmediatelyPostComment = false;
+ isPreviousCharPostComment = false;
+ isCharImmediatelyPostLineComment = false;
+ isCharImmediatelyPostOpenBlock = false;
+ isCharImmediatelyPostCloseBlock = false;
+ isCharImmediatelyPostTemplate = false;
+ traceLineNumber++;
+
+ while (!isLineReady)
+ {
+ if (shouldReparseCurrentChar)
+ shouldReparseCurrentChar = false;
+ else if (!getNextChar())
+ {
+ breakLine();
+ return beautify(readyFormattedLine);
+ }
+ else // stuff to do when reading a new character...
+ {
+ // make sure that a virgin '{' at the begining of the file will be treated as a block...
+ if (isInVirginLine && currentChar == '{'
+ && currentLineBeginsWithBracket // lineBeginsWith('{')
+ && previousCommandChar == ' ')
+ previousCommandChar = '{';
+ if (clearNonInStatement)
+ {
+ isNonInStatementArray = false;
+ clearNonInStatement = false;
+ }
+ if (isInHorstmannRunIn)
+ isInLineBreak = false;
+ if (!isWhiteSpace(currentChar))
+ isInHorstmannRunIn = false;
+ isPreviousCharPostComment = isCharImmediatelyPostComment;
+ isCharImmediatelyPostComment = false;
+ isCharImmediatelyPostTemplate = false;
+ isCharImmediatelyPostReturn = false;
+ isCharImmediatelyPostOperator = false;
+ isCharImmediatelyPostOpenBlock = false;
+ isCharImmediatelyPostCloseBlock = false;
+ }
+
+// if (inLineNumber >= 7)
+// int x = 1;
+
+ if (shouldBreakLineAtNextChar && !isWhiteSpace(currentChar))
+ {
+ isInLineBreak = true;
+ shouldBreakLineAtNextChar = false;
+ }
+
+ if (isInExecSQL && !passedSemicolon)
+ {
+ if (currentChar == ';')
+ passedSemicolon = true;
+ appendCurrentChar();
+ continue;
+ }
+
+ if (isInLineComment)
+ {
+ formatLineCommentBody();
+ continue;
+ }
+ else if (isInComment)
+ {
+ formatCommentBody();
+ continue;
+ }
+
+ // not in line comment or comment
+
+ else if (isInQuote)
+ {
+ formatQuoteBody();
+ continue;
+ }
+
+ if (isSequenceReached("//"))
+ {
+ formatLineCommentOpener();
+ continue;
+ }
+ else if (isSequenceReached("/*"))
+ {
+ formatCommentOpener();
+ continue;
+ }
+ else if (currentChar == '"' || currentChar == '\'')
+ {
+ formatQuoteOpener();
+ continue;
+ }
+ // treat these preprocessor statements as a line comment
+ else if (currentChar =='#')
+ {
+ if (isSequenceReached("#region")
+ || isSequenceReached("#endregion")
+ || isSequenceReached("#error")
+ || isSequenceReached("#warning"))
+ {
+ // check for horstmann run-in
+ if (formattedLine[0] == '{')
+ {
+ isInLineBreak = true;
+ isInHorstmannRunIn = false;
+ }
+ isInLineComment = true;
+ appendCurrentChar();
+ continue;
+ }
+ }
+
+ if (isInPreprocessor)
+ {
+ appendCurrentChar();
+ continue;
+ }
+
+ // handle white space - needed to simplify the rest.
+ if (isWhiteSpace(currentChar))
+ {
+ appendCurrentChar();
+ continue;
+ }
+
+ /* not in MIDDLE of quote or comment or SQL or white-space of any type ... */
+
+ // check if in preprocessor
+ // ** isInPreprocessor will be automatically reset at the begining
+ // of a new line in getnextChar()
+ if (currentChar == '#')
+ {
+ isInPreprocessor = true;
+ // check for horstmann run-in
+ if (formattedLine[0] == '{')
+ {
+ isInLineBreak = true;
+ isInHorstmannRunIn = false;
+ }
+ processPreprocessor();
+ // need to fall thru here to reset the variables
+ }
+
+ /* not in preprocessor ... */
+
+ if (isImmediatelyPostComment)
+ {
+ isImmediatelyPostComment = false;
+ isCharImmediatelyPostComment = true;
+ }
+
+ if (isImmediatelyPostLineComment)
+ {
+ isImmediatelyPostLineComment = false;
+ isCharImmediatelyPostLineComment = true;
+ }
+
+ if (isImmediatelyPostReturn)
+ {
+ isImmediatelyPostReturn = false;
+ isCharImmediatelyPostReturn = true;
+ }
+
+ if (isImmediatelyPostOperator)
+ {
+ isImmediatelyPostOperator = false;
+ isCharImmediatelyPostOperator = true;
+ }
+
+ // reset isImmediatelyPostHeader information
+ if (isImmediatelyPostHeader)
+ {
+ // should brackets be added
+ if (currentChar != '{' && shouldAddBrackets)
+ {
+ bool bracketsAdded = addBracketsToStatement();
+ if (bracketsAdded && !shouldAddOneLineBrackets)
+ {
+ size_t firstText = currentLine.find_first_not_of(" \t");
+ assert(firstText != string::npos);
+ if ((int) firstText == charNum)
+ breakCurrentOneLineBlock = true;
+ }
+ }
+
+ // Make sure headers are broken from their succeeding blocks
+ // (e.g.
+ // if (isFoo) DoBar();
+ // should become
+ // if (isFoo)
+ // DoBar;
+ // )
+ // But treat else if() as a special case which should not be broken!
+ if (shouldBreakOneLineStatements
+ && isOkToBreakBlock(bracketTypeStack->back()))
+ {
+ // if may break 'else if()'s, then simply break the line
+ if (shouldBreakElseIfs)
+ isInLineBreak = true;
+ }
+
+ isImmediatelyPostHeader = false;
+ }
+
+ if (passedSemicolon) // need to break the formattedLine
+ {
+ passedSemicolon = false;
+ if (parenStack->back() == 0 && currentChar != ';') // allow ;;
+ {
+ // does a one-line statement have ending comments?
+ if (isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE))
+ {
+ size_t blockEnd = currentLine.rfind(AS_CLOSE_BRACKET);
+ assert(blockEnd != string::npos);
+ // move ending comments to this formattedLine
+ if (isBeforeAnyLineEndComment(blockEnd))
+ {
+ size_t commentStart = currentLine.find_first_not_of(" \t", blockEnd + 1);
+ assert(commentStart != string::npos);
+ assert((currentLine.compare(commentStart, 2, "//") == 0)
+ || (currentLine.compare(commentStart, 2, "/*") == 0));
+ size_t commentLength = currentLine.length() - commentStart;
+ formattedLine.append(getIndentLength() - 1, ' ');
+ formattedLine.append(currentLine, commentStart, commentLength);
+ currentLine.erase(commentStart, commentLength);
+ }
+ }
+ isInExecSQL = false;
+ shouldReparseCurrentChar = true;
+ isInLineBreak = true;
+ if (needHeaderOpeningBracket)
+ {
+ isCharImmediatelyPostCloseBlock = true;
+ needHeaderOpeningBracket = false;
+ }
+ continue;
+ }
+ }
+
+ if (passedColon)
+ {
+ passedColon = false;
+ if (parenStack->back() == 0 && !isBeforeAnyComment())
+ {
+ shouldReparseCurrentChar = true;
+ isInLineBreak = true;
+ continue;
+ }
+ }
+
+ // Check if in template declaration, e.g. foo<bar> or foo<bar,fig>
+ // If so, set isInTemplate to true
+ if (!isInTemplate && currentChar == '<')
+ {
+ int maxTemplateDepth = 0;
+ templateDepth = 0;
+ for (size_t i = charNum;
+ i < currentLine.length();
+ i++)
+ {
+ char currentChar = currentLine[i];
+
+ if (currentChar == '<')
+ {
+ templateDepth++;
+ maxTemplateDepth++;
+ }
+ else if (currentChar == '>')
+ {
+ templateDepth--;
+ if (templateDepth == 0)
+ {
+ // this is a template!
+ isInTemplate = true;
+ templateDepth = maxTemplateDepth;
+ break;
+ }
+ }
+ else if (currentLine.compare(i, 2, "&&") == 0
+ || currentLine.compare(i, 2, "||") == 0)
+ {
+ // this is not a template -> leave...
+ isInTemplate = false;
+ break;
+ }
+ else if (currentChar == ',' // comma, e.g. A<int, char>
+ || currentChar == '&' // reference, e.g. A<int&>
+ || currentChar == '*' // pointer, e.g. A<int*>
+ || currentChar == ':' // ::, e.g. std::string
+ || currentChar == '[' // [] e.g. string[]
+ || currentChar == ']' // [] e.g. string[]
+ || currentChar == '(' // (...) e.g. function definition
+ || currentChar == ')') // (...) e.g. function definition
+ {
+ continue;
+ }
+ else if (!isLegalNameChar(currentChar) && !isWhiteSpace(currentChar))
+ {
+ // this is not a template -> leave...
+ isInTemplate = false;
+ break;
+ }
+ }
+ }
+
+ // handle parenthesies
+ if (currentChar == '(' || currentChar == '[' || (isInTemplate && currentChar == '<'))
+ {
+ parenStack->back()++;
+ if (currentChar == '[')
+ isInBlParen = true;
+ }
+ else if (currentChar == ')' || currentChar == ']' || (isInTemplate && currentChar == '>'))
+ {
+ parenStack->back()--;
+ if (isInTemplate && currentChar == '>')
+ {
+ templateDepth--;
+ if (templateDepth == 0)
+ {
+ isInTemplate = false;
+ isCharImmediatelyPostTemplate = true;
+ }
+ }
+
+ // check if this parenthesis closes a header, e.g. if (...), while (...)
+ if (isInHeader && parenStack->back() == 0)
+ {
+ isInHeader = false;
+ isImmediatelyPostHeader = true;
+ }
+ if (currentChar == ']')
+ isInBlParen = false;
+ if (currentChar == ')')
+ {
+ foundCastOperator = false;
+ if (parenStack->back() == 0)
+ isInAsm = false;
+ }
+ }
+
+ // handle brackets
+ if (currentChar == '{' || currentChar == '}')
+ {
+ // if appendOpeningBracket this was already done for the original bracket
+ if (currentChar == '{' && !appendOpeningBracket)
+ {
+ BracketType newBracketType = getBracketType();
+ foundNamespaceHeader = false;
+ foundClassHeader = false;
+ foundStructHeader = false;
+ foundInterfaceHeader = false;
+ foundPreDefinitionHeader = false;
+ foundPreCommandHeader = false;
+ isInPotentialCalculation = false;
+ isJavaStaticConstructor = false;
+ needHeaderOpeningBracket = false;
+
+ isPreviousBracketBlockRelated = !isBracketType(newBracketType, ARRAY_TYPE);
+ bracketTypeStack->push_back(newBracketType);
+ preBracketHeaderStack->push_back(currentHeader);
+ currentHeader = NULL;
+ structStack->push_back(isInIndentableStruct);
+ if (isBracketType(newBracketType, STRUCT_TYPE) && isCStyle())
+ isInIndentableStruct = isStructAccessModified(currentLine, charNum);
+ else
+ isInIndentableStruct = false;
+ }
+
+ // this must be done before the bracketTypeStack is popped
+ BracketType bracketType = bracketTypeStack->back();
+ bool isOpeningArrayBracket = (isBracketType(bracketType, ARRAY_TYPE)
+ && bracketTypeStack->size() >= 2
+ && !isBracketType((*bracketTypeStack)[bracketTypeStack->size()-2], ARRAY_TYPE)
+ );
+
+ if (currentChar == '}')
+ {
+ // if a request has been made to append a post block empty line,
+ // but the block exists immediately before a closing bracket,
+ // then there is no need for the post block empty line.
+ isAppendPostBlockEmptyLineRequested = false;
+ breakCurrentOneLineBlock = false;
+ isInAsmBlock = false;
+
+ // added for release 1.24
+ // TODO: remove at the appropriate time
+ assert(isInAsm == false);
+ assert(isInAsmOneLine == false);
+ assert(isInQuote == false);
+ isInAsm = isInAsmOneLine = isInQuote = false;
+ // end remove
+
+ if (bracketTypeStack->size() > 1)
+ {
+ previousBracketType = bracketTypeStack->back();
+ bracketTypeStack->pop_back();
+ isPreviousBracketBlockRelated = !isBracketType(bracketType, ARRAY_TYPE);
+ }
+ else
+ {
+ previousBracketType = NULL_TYPE;
+ isPreviousBracketBlockRelated = false;
+ }
+
+ if (!preBracketHeaderStack->empty())
+ {
+ currentHeader = preBracketHeaderStack->back();
+ preBracketHeaderStack->pop_back();
+ }
+ else
+ currentHeader = NULL;
+
+ if (!structStack->empty())
+ {
+ isInIndentableStruct = structStack->back();
+ structStack->pop_back();
+ }
+ else
+ isInIndentableStruct = false;
+
+ if (isBracketType(bracketType, ARRAY_NIS_TYPE) && !isBracketType(bracketType, SINGLE_LINE_TYPE))
+ clearNonInStatement = true;
+ }
+
+ // format brackets
+ appendOpeningBracket = false;
+ if (isBracketType(bracketType, ARRAY_TYPE))
+ {
+ formatArrayBrackets(bracketType, isOpeningArrayBracket);
+ }
+ else
+ {
+ if (currentChar == '{')
+ formatOpeningBracket(bracketType);
+ else
+ formatClosingBracket(bracketType);
+ }
+ continue;
+ }
+
+ if ((((previousCommandChar == '{' && isPreviousBracketBlockRelated)
+ || ((previousCommandChar == '}'
+ && !isImmediatelyPostEmptyBlock
+ && isPreviousBracketBlockRelated
+ && !isPreviousCharPostComment // Fixes wrongly appended newlines after '}' immediately after comments
+ && peekNextChar() != ' '
+ && !isBracketType(previousBracketType, DEFINITION_TYPE))
+ && !isBracketType(bracketTypeStack->back(), DEFINITION_TYPE)))
+ && isOkToBreakBlock(bracketTypeStack->back()))
+ // check for array
+ || (isBracketType(bracketTypeStack->back(), ARRAY_TYPE)
+ && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)
+ && isNonInStatementArray))
+ {
+ isCharImmediatelyPostOpenBlock = (previousCommandChar == '{');
+ isCharImmediatelyPostCloseBlock = (previousCommandChar == '}');
+
+ if (isCharImmediatelyPostOpenBlock
+ && !isCharImmediatelyPostComment
+ && !isCharImmediatelyPostLineComment)
+ {
+ previousCommandChar = ' ';
+
+ if (bracketFormatMode == NONE_MODE)
+ {
+ if (shouldBreakOneLineBlocks
+ && isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE))
+ isInLineBreak = true;
+ else if (currentLineBeginsWithBracket)
+ formatRunIn();
+ else
+ breakLine();
+ }
+ else if (bracketFormatMode == HORSTMANN_MODE
+ && currentChar != '#')
+ formatRunIn();
+ else
+ isInLineBreak = true;
+ }
+ else if (isCharImmediatelyPostCloseBlock
+ && shouldBreakOneLineStatements
+ && (isLegalNameChar(currentChar) && currentChar != '.')
+ && !isCharImmediatelyPostComment)
+ {
+ previousCommandChar = ' ';
+ isInLineBreak = true;
+ }
+ }
+
+ // reset block handling flags
+ isImmediatelyPostEmptyBlock = false;
+
+ // look for headers
+ bool isPotentialHeader = isCharPotentialHeader(currentLine, charNum);
+
+ if (isPotentialHeader && !isInTemplate)
+ {
+ isNonParenHeader = false;
+ foundClosingHeader = false;
+ newHeader = findHeader(headers);
+
+ if (newHeader != NULL)
+ {
+ char peekChar = ASBase::peekNextChar(currentLine, charNum + newHeader->length() - 1);
+
+ // is not a header if part of a definition
+ if (peekChar == ',' || peekChar == ')')
+ newHeader = NULL;
+ // the following accessor definitions are NOT headers
+ // goto default; is NOT a header
+ else if ((newHeader == &AS_GET || newHeader == &AS_SET || newHeader == &AS_DEFAULT)
+ && peekChar == ';')
+ {
+ newHeader = NULL;
+ }
+ }
+
+ if (newHeader != NULL)
+ {
+ const string *previousHeader;
+
+ // recognize closing headers of do..while, if..else, try..catch..finally
+ if ((newHeader == &AS_ELSE && currentHeader == &AS_IF)
+ || (newHeader == &AS_WHILE && currentHeader == &AS_DO)
+ || (newHeader == &AS_CATCH && currentHeader == &AS_TRY)
+ || (newHeader == &AS_CATCH && currentHeader == &AS_CATCH)
+ || (newHeader == &AS_FINALLY && currentHeader == &AS_TRY)
+ || (newHeader == &AS_FINALLY && currentHeader == &AS_CATCH)
+ || (newHeader == &AS_SET && currentHeader == &AS_GET)
+ || (newHeader == &AS_REMOVE && currentHeader == &AS_ADD))
+ foundClosingHeader = true;
+
+ previousHeader = currentHeader;
+ currentHeader = newHeader;
+ needHeaderOpeningBracket = true;
+
+ if (foundClosingHeader && previousNonWSChar == '}')
+ {
+ if (isOkToBreakBlock(bracketTypeStack->back()))
+ isLineBreakBeforeClosingHeader();
+
+ // get the adjustment for a comment following the closing header
+ if (isInLineBreak)
+ nextLineSpacePadNum = getNextLineCommentAdjustment();
+ else
+ spacePadNum = getCurrentLineCommentAdjustment();
+ }
+
+ // check if the found header is non-paren header
+ isNonParenHeader = findHeader(nonParenHeaders) != NULL;
+
+ // join 'else if' statements
+ if (currentHeader == &AS_IF && previousHeader == &AS_ELSE && isInLineBreak
+ && !shouldBreakElseIfs && !isCharImmediatelyPostLineComment)
+ {
+ // 'else' must be last thing on the line, but must not be #else
+ size_t start = formattedLine.length() >= 6 ? formattedLine.length()-6 : 0;
+ if (formattedLine.find("else", start) != string::npos
+ && formattedLine.find("#else", start) == string::npos)
+ {
+ appendSpacePad();
+ isInLineBreak = false;
+ }
+ }
+
+ appendSequence(*currentHeader);
+ goForward(currentHeader->length() - 1);
+ // if a paren-header is found add a space after it, if needed
+ // this checks currentLine, appendSpacePad() checks formattedLine
+ // in C# 'catch' can be either a paren or non-paren header
+ if (shouldPadHeader
+ && (!isNonParenHeader || (currentHeader == &AS_CATCH && peekNextChar() == '('))
+ && charNum < (int) currentLine.length() && !isWhiteSpace(currentLine[charNum+1]))
+ appendSpacePad();
+
+ // Signal that a header has been reached
+ // *** But treat a closing while() (as in do...while)
+ // as if it were NOT a header since a closing while()
+ // should never have a block after it!
+ if (!(foundClosingHeader && currentHeader == &AS_WHILE))
+ {
+ isInHeader = true;
+
+ // in C# 'catch' and 'delegate' can be a paren or non-paren header
+ if (isNonParenHeader && !isSharpStyleWithParen(currentHeader))
+ {
+ isImmediatelyPostHeader = true;
+ isInHeader = false;
+ }
+ }
+
+ if (shouldBreakBlocks
+ && isOkToBreakBlock(bracketTypeStack->back()))
+ {
+ if (previousHeader == NULL
+ && !foundClosingHeader
+ && !isCharImmediatelyPostOpenBlock
+ && !isImmediatelyPostCommentOnly)
+ {
+ isPrependPostBlockEmptyLineRequested = true;
+ }
+
+ if (currentHeader == &AS_ELSE
+ || currentHeader == &AS_CATCH
+ || currentHeader == &AS_FINALLY
+ || foundClosingHeader)
+ {
+ isPrependPostBlockEmptyLineRequested = false;
+ }
+
+ if (shouldBreakClosingHeaderBlocks
+ && isCharImmediatelyPostCloseBlock
+ && !isImmediatelyPostCommentOnly
+ && currentHeader != &AS_WHILE) // closing do-while block
+ {
+ isPrependPostBlockEmptyLineRequested = true;
+ }
+
+ }
+
+ continue;
+ }
+ else if ((newHeader = findHeader(preDefinitionHeaders)) != NULL
+ && parenStack->back() == 0)
+ {
+ if (newHeader == &AS_NAMESPACE)
+ foundNamespaceHeader = true;
+ if (newHeader == &AS_CLASS)
+ foundClassHeader = true;
+ if (newHeader == &AS_STRUCT)
+ foundStructHeader = true;
+ if (newHeader == &AS_INTERFACE)
+ foundInterfaceHeader = true;
+ foundPreDefinitionHeader = true;
+ appendSequence(*newHeader);
+ goForward(newHeader->length() - 1);
+
+ continue;
+ }
+ else if ((newHeader = findHeader(preCommandHeaders)) != NULL)
+ {
+ if (!(*newHeader == AS_CONST && previousCommandChar != ')')) // 'const' member functions is a command bracket
+ foundPreCommandHeader = true;
+ appendSequence(*newHeader);
+ goForward(newHeader->length() - 1);
+
+ continue;
+ }
+ else if ((newHeader = findHeader(castOperators)) != NULL)
+ {
+ foundCastOperator = true;
+ appendSequence(*newHeader);
+ goForward(newHeader->length() - 1);
+ continue;
+ }
+ } // (isPotentialHeader && !isInTemplate)
+
+ if (isInLineBreak) // OK to break line here
+ {
+ breakLine();
+ if (isInVirginLine) // adjust for the first line
+ {
+ lineCommentNoBeautify = lineCommentNoIndent;
+ lineCommentNoIndent = false;
+ }
+ }
+
+ if (previousNonWSChar == '}' || currentChar == ';')
+ {
+ if (currentChar == ';')
+ {
+ if ((shouldBreakOneLineStatements
+ || isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE))
+ && isOkToBreakBlock(bracketTypeStack->back()))
+ {
+ passedSemicolon = true;
+ }
+
+ // append post block empty line for unbracketed header
+ if (shouldBreakBlocks && currentHeader != NULL && parenStack->back() == 0)
+ {
+ isAppendPostBlockEmptyLineRequested = true;
+ }
+ }
+
+ // end of block if a closing bracket was found
+ // or an opening bracket was not found (';' closes)
+ if (currentChar != ';'
+ || (needHeaderOpeningBracket && parenStack->back() == 0))
+ currentHeader = NULL;
+
+ foundQuestionMark = false;
+ foundNamespaceHeader = false;
+ foundClassHeader = false;
+ foundStructHeader = false;
+ foundInterfaceHeader = false;
+ foundPreDefinitionHeader = false;
+ foundPreCommandHeader = false;
+ foundCastOperator = false;
+ isInPotentialCalculation = false;
+ isSharpAccessor = false;
+ isSharpDelegate = false;
+ isInExtern = false;
+ nonInStatementBracket = 0;
+ }
+
+ if (currentChar == ':' && shouldBreakOneLineStatements)
+ {
+ if (isInCase
+ && previousChar != ':' // not part of '::'
+ && peekNextChar() != ':') // not part of '::'
+ {
+ isInCase = false;
+ passedColon = true;
+ }
+ else if (isCStyle() // for C/C++ only
+ && !foundQuestionMark // not in a ... ? ... : ... sequence
+ && !foundPreDefinitionHeader // not in a definition block (e.g. class foo : public bar
+ && previousCommandChar != ')' // not immediately after closing paren of a method header, e.g. ASFormatter::ASFormatter(...) : ASBeautifier(...)
+ && previousChar != ':' // not part of '::'
+ && peekNextChar() != ':' // not part of '::'
+ && !isdigit(peekNextChar()) // not a bit field
+ && !isInAsm // not in extended assembler
+ && !isInAsmOneLine // not in extended assembler
+ && !isInAsmBlock) // not in extended assembler
+ {
+ passedColon = true;
+ }
+ }
+
+ if (currentChar == '?')
+ foundQuestionMark = true;
+
+ if (isPotentialHeader && !isInTemplate)
+ {
+ if (findKeyword(currentLine, charNum, AS_CASE)
+ || findKeyword(currentLine, charNum, AS_DEFAULT))
+ isInCase = true;
+
+ if (findKeyword(currentLine, charNum, AS_NEW))
+ isInPotentialCalculation = false;
+
+ if (findKeyword(currentLine, charNum, AS_RETURN))
+ {
+ isInPotentialCalculation = true; // return is the same as an = sign
+ isImmediatelyPostReturn = true;
+ }
+
+ if (findKeyword(currentLine, charNum, AS_OPERATOR))
+ isImmediatelyPostOperator = true;
+
+ if (isCStyle() && findKeyword(currentLine, charNum, AS_EXTERN))
+ isInExtern = true;
+
+ if (isCStyle() && isExecSQL(currentLine, charNum))
+ isInExecSQL = true;
+
+ if (isCStyle())
+ {
+ if (findKeyword(currentLine, charNum, AS_ASM)
+ || findKeyword(currentLine, charNum, AS__ASM__))
+ {
+ isInAsm = true;
+ }
+ else if (findKeyword(currentLine, charNum, AS_MS_ASM) // microsoft specific
+ || findKeyword(currentLine, charNum, AS_MS__ASM))
+ {
+ int index = 4;
+ if (peekNextChar() == '_') // check for __asm
+ index = 5;
+
+ char peekedChar = ASBase::peekNextChar(currentLine, charNum + index);
+ if (peekedChar == '{' || peekedChar == ' ')
+ isInAsmBlock = true;
+ else
+ isInAsmOneLine = true;
+ }
+ }
+
+ if (isJavaStyle()
+ && (findKeyword(currentLine, charNum, AS_STATIC)
+ && isNextCharOpeningBracket(charNum + 6)))
+ isJavaStaticConstructor = true;
+
+ if (isSharpStyle()
+ && (findKeyword(currentLine, charNum, AS_DELEGATE)
+ || findKeyword(currentLine, charNum, AS_UNCHECKED)))
+ isSharpDelegate = true;
+
+ // append the entire name
+ string name = getCurrentWord(currentLine, charNum);
+ appendSequence(name);
+ goForward(name.length() - 1);
+
+ continue;
+
+ } // (isPotentialHeader && !isInTemplate)
+
+ // determine if this is a potential calculation
+
+ bool isPotentialOperator = isCharPotentialOperator(currentChar);
+ newHeader = NULL;
+
+ if (isPotentialOperator)
+ {
+ newHeader = findOperator(operators);
+
+ if (newHeader != NULL)
+ {
+ // correct mistake of two >> closing a template
+ if (isInTemplate && (newHeader == &AS_GR_GR || newHeader == &AS_GR_GR_GR))
+ newHeader = &AS_GR;
+
+ if (!isInPotentialCalculation)
+ {
+ // must determine if newHeader is an assignment operator
+ // do NOT use findOperator!!!
+ if (find(assignmentOperators->begin(), assignmentOperators->end(), newHeader)
+ != assignmentOperators->end())
+ {
+ char peekedChar = peekNextChar();
+ isInPotentialCalculation = (!(newHeader == &AS_EQUAL && peekedChar == '*')
+ && !(newHeader == &AS_EQUAL && peekedChar == '&'));
+ }
+ }
+ }
+ }
+
+ // process pointers and references
+ // check new header to elimnate things like '&&' sequence
+ if (isCStyle()
+ && (newHeader == &AS_MULT || newHeader == &AS_BIT_AND)
+ && isPointerOrReference()
+ && !isDereferenceOrAddressOf())
+ {
+ formatPointerOrReference();
+ continue;
+ }
+
+ if (shouldPadOperators && newHeader != NULL)
+ {
+ padOperators(newHeader);
+ continue;
+ }
+
+ // pad commas and semi-colons
+ if (currentChar == ';'
+ || (currentChar == ',' && shouldPadOperators))
+ {
+ char nextChar = ' ';
+ if (charNum + 1 < (int) currentLine.length())
+ nextChar = currentLine[charNum+1];
+ if (!isWhiteSpace(nextChar)
+ && nextChar != '}'
+ && nextChar != ')'
+ && nextChar != ']'
+ && nextChar != '>'
+ && nextChar != ';'
+ && !isBeforeAnyComment()
+ /* && !(isBracketType(bracketTypeStack->back(), ARRAY_TYPE)) */
+ )
+ {
+ appendCurrentChar();
+ appendSpaceAfter();
+ continue;
+ }
+ }
+
+ if ((shouldPadParensOutside || shouldPadParensInside || shouldUnPadParens)
+ && (currentChar == '(' || currentChar == ')'))
+ {
+ padParens();
+ continue;
+ }
+
+ appendCurrentChar();
+ } // end of while loop * end of while loop * end of while loop * end of while loop
+
+ // return a beautified (i.e. correctly indented) line.
+
+ string beautifiedLine;
+ size_t readyFormattedLineLength = trim(readyFormattedLine).length();
+
+ if (prependEmptyLine // prepend a blank line before this formatted line
+ && readyFormattedLineLength > 0
+ && previousReadyFormattedLineLength > 0)
+ {
+ isLineReady = true; // signal a waiting readyFormattedLine
+ beautifiedLine = beautify("");
+ previousReadyFormattedLineLength = 0;
+ }
+ else // format the current formatted line
+ {
+ isLineReady = false;
+ horstmannIndentInStatement = horstmannIndentChars;
+ beautifiedLine = beautify(readyFormattedLine);
+ previousReadyFormattedLineLength = readyFormattedLineLength;
+ // the enhancer is not called for new empty lines
+ // or no-indent line comments
+ if (!lineCommentNoBeautify)
+ enhancer->enhance(beautifiedLine, isInBeautifySQL);
+ horstmannIndentChars = 0;
+ lineCommentNoBeautify = lineCommentNoIndent;
+ lineCommentNoIndent = false;
+ isInBeautifySQL = isInExecSQL;
+ }
+
+ prependEmptyLine = false;
+ return beautifiedLine;
+}
+
+
+/**
+ * check if there are any indented lines ready to be read by nextLine()
+ *
+ * @return are there any indented lines ready?
+ */
+bool ASFormatter::hasMoreLines() const
+{
+ return !endOfCodeReached;
+}
+
+/**
+ * comparison function for BracketType enum
+ */
+bool ASFormatter::isBracketType(BracketType a, BracketType b) const
+{
+ return ((a & b) == b);
+}
+
+/**
+ * set the formatting style.
+ *
+ * @param mode the formatting style.
+ */
+void ASFormatter::setFormattingStyle(FormatStyle style)
+{
+ formattingStyle = style;
+}
+
+/**
+ * set the add brackets mode.
+ * options:
+ * true brackets added to headers for single line statements.
+ * false brackets NOT added to headers for single line statements.
+ *
+ * @param mode the bracket formatting mode.
+ */
+void ASFormatter::setAddBracketsMode(bool state)
+{
+ shouldAddBrackets = state;
+}
+
+/**
+ * set the add one line brackets mode.
+ * options:
+ * true one line brackets added to headers for single line statements.
+ * false one line brackets NOT added to headers for single line statements.
+ *
+ * @param mode the bracket formatting mode.
+ */
+void ASFormatter::setAddOneLineBracketsMode(bool state)
+{
+ shouldAddBrackets = state;
+ shouldAddOneLineBrackets = state;
+}
+
+/**
+ * set the bracket formatting mode.
+ * options:
+ *
+ * @param mode the bracket formatting mode.
+ */
+void ASFormatter::setBracketFormatMode(BracketMode mode)
+{
+ bracketFormatMode = mode;
+}
+
+/**
+ * set closing header bracket breaking mode
+ * options:
+ * true brackets just before closing headers (e.g. 'else', 'catch')
+ * will be broken, even if standard brackets are attached.
+ * false closing header brackets will be treated as standard brackets.
+ *
+ * @param state the closing header bracket breaking mode.
+ */
+void ASFormatter::setBreakClosingHeaderBracketsMode(bool state)
+{
+ shouldBreakClosingHeaderBrackets = state;
+}
+
+/**
+ * set 'else if()' breaking mode
+ * options:
+ * true 'else' headers will be broken from their succeeding 'if' headers.
+ * false 'else' headers will be attached to their succeeding 'if' headers.
+ *
+ * @param state the 'else if()' breaking mode.
+ */
+void ASFormatter::setBreakElseIfsMode(bool state)
+{
+ shouldBreakElseIfs = state;
+}
+
+/**
+ * set operator padding mode.
+ * options:
+ * true statement operators will be padded with spaces around them.
+ * false statement operators will not be padded.
+ *
+ * @param state the padding mode.
+ */
+void ASFormatter::setOperatorPaddingMode(bool state)
+{
+ shouldPadOperators = state;
+}
+
+/**
+ * set parenthesis outside padding mode.
+ * options:
+ * true statement parenthesiss will be padded with spaces around them.
+ * false statement parenthesiss will not be padded.
+ *
+ * @param state the padding mode.
+ */
+void ASFormatter::setParensOutsidePaddingMode(bool state)
+{
+ shouldPadParensOutside = state;
+}
+
+/**
+ * set parenthesis inside padding mode.
+ * options:
+ * true statement parenthesis will be padded with spaces around them.
+ * false statement parenthesis will not be padded.
+ *
+ * @param state the padding mode.
+ */
+void ASFormatter::setParensInsidePaddingMode(bool state)
+{
+ shouldPadParensInside = state;
+}
+
+/**
+ * set header padding mode.
+ * options:
+ * true headers will be padded with spaces around them.
+ * false headers will not be padded.
+ *
+ * @param state the padding mode.
+ */
+void ASFormatter::setParensHeaderPaddingMode(bool state)
+{
+ shouldPadHeader = state;
+}
+
+/**
+ * set parenthesis unpadding mode.
+ * options:
+ * true statement parenthesis will be unpadded with spaces removed around them.
+ * false statement parenthesis will not be unpadded.
+ *
+ * @param state the padding mode.
+ */
+void ASFormatter::setParensUnPaddingMode(bool state)
+{
+ shouldUnPadParens = state;
+}
+
+/**
+ * set option to break/not break one-line blocks
+ *
+ * @param state true = break, false = don't break.
+ */
+void ASFormatter::setBreakOneLineBlocksMode(bool state)
+{
+ shouldBreakOneLineBlocks = state;
+}
+
+/**
+ * set option to break/not break lines consisting of multiple statements.
+ *
+ * @param state true = break, false = don't break.
+ */
+void ASFormatter::setSingleStatementsMode(bool state)
+{
+ shouldBreakOneLineStatements = state;
+}
+
+/**
+ * set option to convert tabs to spaces.
+ *
+ * @param state true = convert, false = don't convert.
+ */
+void ASFormatter::setTabSpaceConversionMode(bool state)
+{
+ shouldConvertTabs = state;
+}
+
+/**
+ * set option to indent comments in column 1.
+ *
+ * @param state true = indent, false = don't indent.
+ */
+void ASFormatter::setIndentCol1CommentsMode(bool state)
+{
+ shouldIndentCol1Comments = state;
+}
+
+/**
+ * set option to force all line ends to a particular style.
+ *
+ * @param fmt format enum value
+ */
+void ASFormatter::setLineEndFormat(LineEndFormat fmt)
+{
+ lineEnd = fmt;
+}
+
+/**
+ * set option to break unrelated blocks of code with empty lines.
+ *
+ * @param state true = convert, false = don't convert.
+ */
+void ASFormatter::setBreakBlocksMode(bool state)
+{
+ shouldBreakBlocks = state;
+}
+
+/**
+ * set option to break closing header blocks of code (such as 'else', 'catch', ...) with empty lines.
+ *
+ * @param state true = convert, false = don't convert.
+ */
+void ASFormatter::setBreakClosingHeaderBlocksMode(bool state)
+{
+ shouldBreakClosingHeaderBlocks = state;
+}
+
+/**
+ * set option to delete empty lines.
+ *
+ * @param state true = delete, false = don't delete.
+ */
+void ASFormatter::setDeleteEmptyLinesMode(bool state)
+{
+ shouldDeleteEmptyLines = state;
+}
+
+/**
+ * set the pointer alignment.
+ * options:
+ *
+ * @param alignment the pointer alignment.
+ */
+void ASFormatter::setPointerAlignment(PointerAlign alignment)
+{
+ pointerAlignment = alignment;
+}
+
+/**
+ * jump over several characters.
+ *
+ * @param i the number of characters to jump over.
+ */
+void ASFormatter::goForward(int i)
+{
+ while (--i >= 0)
+ getNextChar();
+}
+
+/**
+ * peek at the next unread character.
+ *
+ * @return the next unread character.
+ */
+char ASFormatter::peekNextChar() const
+{
+ char ch = ' ';
+ size_t peekNum = currentLine.find_first_not_of(" \t", charNum + 1);
+
+ if (peekNum == string::npos)
+ return ch;
+
+ ch = currentLine[peekNum];
+
+ return ch;
+}
+
+/**
+ * check if current placement is before a comment
+ *
+ * @return is before a comment.
+ */
+bool ASFormatter::isBeforeComment() const
+{
+ bool foundComment = false;
+ size_t peekNum = currentLine.find_first_not_of(" \t", charNum + 1);
+
+ if (peekNum == string::npos)
+ return foundComment;
+
+ foundComment = (currentLine.compare(peekNum, 2, "/*") == 0);
+
+ return foundComment;
+}
+
+/**
+ * check if current placement is before a comment or line-comment
+ *
+ * @return is before a comment or line-comment.
+ */
+bool ASFormatter::isBeforeAnyComment() const
+{
+ bool foundComment = false;
+ size_t peekNum = currentLine.find_first_not_of(" \t", charNum + 1);
+
+ if (peekNum == string::npos)
+ return foundComment;
+
+ foundComment = (currentLine.compare(peekNum, 2, "/*") == 0
+ || currentLine.compare(peekNum, 2, "//") == 0);
+
+ return foundComment;
+}
+
+/**
+ * check if current placement is before a comment or line-comment
+ * if a block comment it must be at the end of the line
+ *
+ * @return is before a comment or line-comment.
+ */
+bool ASFormatter::isBeforeAnyLineEndComment(int startPos) const
+{
+ bool foundLineEndComment = false;
+ size_t peekNum = currentLine.find_first_not_of(" \t", startPos + 1);
+
+ if (peekNum != string::npos)
+ {
+ if (currentLine.compare(peekNum, 2, "//") == 0)
+ foundLineEndComment = true;
+ else if (currentLine.compare(peekNum, 2, "/*") == 0)
+ {
+ // comment must be closed on this line with nothing after it
+ size_t endNum = currentLine.find("*/", peekNum + 2);
+ if (endNum != string::npos)
+ {
+ size_t nextChar = currentLine.find_first_not_of(" \t", endNum + 2);
+ if (nextChar == string::npos)
+ foundLineEndComment = true;
+ }
+ }
+ }
+ return foundLineEndComment;
+}
+
+/**
+ * check if current placement is before a comment followed by a line-comment
+ *
+ * @return is before a multiple line-end comment.
+ */
+bool ASFormatter::isBeforeMultipleLineEndComments(int startPos) const
+{
+ bool foundMultipleLineEndComment = false;
+ size_t peekNum = currentLine.find_first_not_of(" \t", startPos + 1);
+
+ if (peekNum != string::npos)
+ {
+ if (currentLine.compare(peekNum, 2, "/*") == 0)
+ {
+ // comment must be closed on this line with nothing after it
+ size_t endNum = currentLine.find("*/", peekNum + 2);
+ if (endNum != string::npos)
+ {
+ size_t nextChar = currentLine.find_first_not_of(" \t", endNum + 2);
+ if (nextChar != string::npos
+ && currentLine.compare(nextChar, 2, "//") == 0)
+ foundMultipleLineEndComment = true;
+ }
+ }
+ }
+ return foundMultipleLineEndComment;
+}
+
+
+/**
+ * get the next character, increasing the current placement in the process.
+ * the new character is inserted into the variable currentChar.
+ *
+ * @return whether succeded to recieve the new character.
+ */
+bool ASFormatter::getNextChar()
+{
+ isInLineBreak = false;
+ previousChar = currentChar;
+
+ if (!isWhiteSpace(currentChar))
+ {
+ previousNonWSChar = currentChar;
+ if (!isInComment && !isInLineComment && !isInQuote
+ && !isImmediatelyPostComment
+ && !isImmediatelyPostLineComment
+ && !isInPreprocessor
+ && !isSequenceReached("/*")
+ && !isSequenceReached("//"))
+ previousCommandChar = currentChar;
+ }
+
+ if (charNum + 1 < (int) currentLine.length()
+ && (!isWhiteSpace(peekNextChar()) || isInComment || isInLineComment))
+ {
+ currentChar = currentLine[++charNum];
+
+ if (shouldConvertTabs && currentChar == '\t')
+ convertTabToSpaces();
+
+ return true;
+ }
+
+ // end of line has been reached
+ return getNextLine();
+}
+
+/**
+ * get the next line of input, increasing the current placement in the process.
+ *
+ * @param sequence the sequence to append.
+ * @return whether succeded in reading the next line.
+ */
+bool ASFormatter::getNextLine(bool emptyLineWasDeleted /*false*/)
+{
+ if (sourceIterator->hasMoreLines())
+ {
+ if (appendOpeningBracket)
+ currentLine = "{"; // append bracket that was removed from the previous line
+ else
+ currentLine = sourceIterator->nextLine(emptyLineWasDeleted);
+ // reset variables for new line
+ inLineNumber++;
+ isInCase = false;
+ isInAsmOneLine = false;
+ isInQuoteContinuation = isInVerbatimQuote | haveLineContinuationChar;
+ haveLineContinuationChar= false;
+ isImmediatelyPostEmptyLine = lineIsEmpty;
+ previousChar = ' ';
+
+ if (currentLine.length() == 0)
+ {
+ currentLine = string(" "); // a null is inserted if this is not done
+ }
+
+ // unless reading in the first line of the file, break a new line.
+ if (!isVirgin)
+ isInLineBreak = true;
+ else
+ isVirgin = false;
+
+ // check if is in preprocessor before line trimming
+ // a blank line after a \ will remove the flag
+ isImmediatelyPostPreprocessor = isInPreprocessor;
+ if (previousNonWSChar != '\\'
+ || isEmptyLine(currentLine))
+ isInPreprocessor = false;
+
+ if (passedSemicolon)
+ isInExecSQL = false;
+ initNewLine();
+ currentChar = currentLine[charNum];
+ if (isInHorstmannRunIn && previousNonWSChar == '{')
+ isInLineBreak = false;
+ isInHorstmannRunIn = false;
+
+ if (shouldConvertTabs && currentChar == '\t')
+ convertTabToSpaces();
+
+ // check for an empty line inside a command bracket.
+ // if yes then read the next line (calls getNextLine recursively).
+ // must be after initNewLine.
+ if (shouldDeleteEmptyLines
+ && lineIsEmpty
+ && isBracketType((*bracketTypeStack)[bracketTypeStack->size()-1], COMMAND_TYPE))
+ {
+ // but do NOT delete an empty line between comments if blocks are being broken
+ if (!(shouldBreakBlocks || shouldBreakClosingHeaderBlocks)
+ || !isImmediatelyPostCommentOnly
+ || !commentAndHeaderFollows())
+ {
+ isInPreprocessor = isImmediatelyPostPreprocessor; // restore
+ lineIsEmpty = false;
+ return getNextLine(true);
+ }
+ }
+
+ return true;
+ }
+ else
+ {
+ endOfCodeReached = true;
+ return false;
+ }
+}
+
+/**
+ * jump over the leading white space in the current line,
+ * IF the line does not begin a comment or is in a preprocessor definition.
+ */
+void ASFormatter::initNewLine()
+{
+ size_t len = currentLine.length();
+ size_t indent = getIndentLength();
+ charNum = 0;
+
+ if (isInPreprocessor || isInQuoteContinuation)
+ return;
+
+ // SQL continuation lines must be adjusted so the leading spaces
+ // is equivalent to the opening EXEC SQL
+ if (isInExecSQL)
+ {
+ // replace leading tabs with spaces
+ // so that continuation indent will be spaces
+ size_t tabCount = 0;
+ size_t i;
+ for (i = 0; i < currentLine.length(); i++)
+ {
+ if (!isWhiteSpace(currentLine[i])) // stop at first text
+ break;
+ if (currentLine[i] == '\t')
+ {
+ size_t numSpaces = indent - ((tabCount + i) % indent);
+ currentLine.replace(i, 1, numSpaces, ' ');
+ tabCount++;
+ i += indent - 1;
+ }
+ }
+ // correct the format if EXEC SQL is not a hanging indent
+ if (i < leadingSpaces)
+ currentLine.insert((size_t)0, leadingSpaces - i, ' ');
+ trimContinuationLine();
+ return;
+ }
+
+ // comment continuation lines must be adjusted so the leading spaces
+ // is equivalent to the opening comment
+ if (isInComment)
+ {
+ if (noTrimCommentContinuation)
+ leadingSpaces = tabIncrementIn = 0;
+ trimContinuationLine();
+ return;
+ }
+
+ // compute leading spaces
+ isImmediatelyPostCommentOnly = lineIsLineCommentOnly || lineEndsInCommentOnly;
+ lineIsLineCommentOnly = false;
+ lineEndsInCommentOnly = false;
+ doesLineStartComment = false;
+ currentLineBeginsWithBracket = false;
+ lineIsEmpty = false;
+ currentLineFirstBracketNum = string::npos;
+ tabIncrementIn = 0;
+
+ for (charNum = 0; isWhiteSpace(currentLine[charNum]) && charNum + 1 < (int) len; charNum++)
+ {
+ if (currentLine[charNum] == '\t')
+ tabIncrementIn += indent - 1 - ((tabIncrementIn + charNum) % indent);
+ }
+ leadingSpaces = charNum + tabIncrementIn;
+
+ if (isSequenceReached("/*"))
+ {
+ doesLineStartComment = true;
+ }
+ else if (isSequenceReached("//"))
+ {
+ lineIsLineCommentOnly = true;
+ }
+ else if (isSequenceReached("{"))
+ {
+ currentLineBeginsWithBracket = true;
+ currentLineFirstBracketNum = charNum;
+ size_t firstText = currentLine.find_first_not_of(" \t", charNum + 1);
+ if (firstText != string::npos)
+ {
+ if (currentLine.compare(firstText, 2, "//") == 0)
+ lineIsLineCommentOnly = true;
+ else if (currentLine.compare(firstText, 2, "/*") == 0
+ || isExecSQL(currentLine, firstText))
+ {
+ // get the extra adjustment
+ size_t j;
+ for (j = charNum + 1; isWhiteSpace(currentLine[j]) && j < firstText; j++)
+ {
+ if (currentLine[j] == '\t')
+ tabIncrementIn += indent - 1 - ((tabIncrementIn + j) % indent);
+ }
+ leadingSpaces = j + tabIncrementIn;
+ if (currentLine.compare(firstText, 2, "/*") == 0)
+ doesLineStartComment = true;
+ }
+ }
+ }
+ else if (isWhiteSpace(currentLine[charNum]) && !(charNum + 1 < (int) currentLine.length()))
+ {
+ lineIsEmpty = true;
+ }
+}
+
+/**
+ * append a string sequence to the current formatted line.
+ * Unless disabled (via canBreakLine == false), first check if a
+ * line-break has been registered, and if so break the
+ * formatted line, and only then append the sequence into
+ * the next formatted line.
+ *
+ * @param sequence the sequence to append.
+ * @param canBreakLine if true, a registered line-break
+ */
+void ASFormatter::appendSequence(const string &sequence, bool canBreakLine)
+{
+ if (canBreakLine && isInLineBreak)
+ breakLine();
+ formattedLine.append(sequence);
+}
+
+/**
+ * append a space to the current formattedline, UNLESS the
+ * last character is already a white-space character.
+ */
+void ASFormatter::appendSpacePad()
+{
+ int len = formattedLine.length();
+ if (len > 0 && !isWhiteSpace(formattedLine[len-1]))
+ {
+ formattedLine.append(1, ' ');
+ spacePadNum++;
+ }
+}
+
+/**
+ * append a space to the current formattedline, UNLESS the
+ * next character is already a white-space character.
+ */
+void ASFormatter::appendSpaceAfter()
+{
+ int len = currentLine.length();
+ if (charNum + 1 < len && !isWhiteSpace(currentLine[charNum+1]))
+ {
+ formattedLine.append(1, ' ');
+ spacePadNum++;
+ }
+}
+
+/**
+ * register a line break for the formatted line.
+ */
+void ASFormatter::breakLine()
+{
+ isLineReady = true;
+ isInLineBreak = false;
+ spacePadNum = nextLineSpacePadNum;
+ nextLineSpacePadNum = 0;
+ formattedLineCommentNum = string::npos;
+
+ // queue an empty line prepend request if one exists
+ prependEmptyLine = isPrependPostBlockEmptyLineRequested;
+
+ readyFormattedLine = formattedLine;
+ if (isAppendPostBlockEmptyLineRequested)
+ {
+ isAppendPostBlockEmptyLineRequested = false;
+ isPrependPostBlockEmptyLineRequested = true;
+ }
+ else
+ {
+ isPrependPostBlockEmptyLineRequested = false;
+ }
+
+ formattedLine = "";
+}
+
+/**
+ * check if the currently reached open-bracket (i.e. '{')
+ * opens a:
+ * - a definition type block (such as a class or namespace),
+ * - a command block (such as a method block)
+ * - a static array
+ * this method takes for granted that the current character
+ * is an opening bracket.
+ *
+ * @return the type of the opened block.
+ */
+BracketType ASFormatter::getBracketType()
+{
+ assert(currentChar == '{');
+
+ BracketType returnVal;
+
+ if ((previousNonWSChar == '='
+ || isBracketType(bracketTypeStack->back(), ARRAY_TYPE))
+ && previousCommandChar != ')')
+ returnVal = ARRAY_TYPE;
+ else if (foundPreDefinitionHeader)
+ {
+ returnVal = DEFINITION_TYPE;
+ if (foundNamespaceHeader)
+ returnVal = (BracketType)(returnVal | NAMESPACE_TYPE);
+ else if (foundClassHeader)
+ returnVal = (BracketType)(returnVal | CLASS_TYPE);
+ else if (foundStructHeader)
+ returnVal = (BracketType)(returnVal | STRUCT_TYPE);
+ else if (foundInterfaceHeader)
+ returnVal = (BracketType)(returnVal | INTERFACE_TYPE);
+ }
+ else
+ {
+ bool isCommandType = (foundPreCommandHeader
+ || (currentHeader != NULL && isNonParenHeader)
+ || (previousCommandChar == ')')
+ || (previousCommandChar == ':' && !foundQuestionMark)
+ || (previousCommandChar == ';')
+ || ((previousCommandChar == '{' || previousCommandChar == '}')
+ && isPreviousBracketBlockRelated)
+ || isJavaStaticConstructor
+ || isSharpDelegate);
+
+ // C# methods containing 'get', 'set', 'add', and 'remove' do NOT end with parens
+ if (!isCommandType && isSharpStyle() && isNextWordSharpNonParenHeader(charNum + 1))
+ {
+ isCommandType = true;
+ isSharpAccessor = true;
+ }
+
+ if (!isCommandType && isInExtern)
+ returnVal = EXTERN_TYPE;
+ else
+ returnVal = (isCommandType ? COMMAND_TYPE : ARRAY_TYPE);
+ }
+
+ if (isOneLineBlockReached(currentLine, charNum))
+ returnVal = (BracketType)(returnVal | SINGLE_LINE_TYPE);
+
+ if (isBracketType(returnVal, ARRAY_TYPE) && isNonInStatementArrayBracket())
+ {
+ returnVal = (BracketType)(returnVal | ARRAY_NIS_TYPE);
+ isNonInStatementArray = true;
+ nonInStatementBracket = formattedLine.length() - 1;
+ }
+
+ return returnVal;
+}
+
+/**
+ * check if a line is empty
+ *
+ * @return whether line is empty
+ */
+bool ASFormatter::isEmptyLine(const string &line) const
+{
+ return line.find_first_not_of(" \t") == string::npos;
+}
+
+/**
+ * Check if the currently reached '*' or '&' character is
+ * a pointer-or-reference symbol, or another operator.
+ * A pointer dereference (*) or an "address of" character (&)
+ * counts as a pointer or reference because it is not an
+ * arithmetic operator.
+ *
+ * @return whether current character is a reference-or-pointer
+ */
+bool ASFormatter::isPointerOrReference() const
+{
+ assert(currentChar == '*' || currentChar == '&');
+
+ if (!isCStyle())
+ return false;
+
+ if (currentChar == '&' && previousChar == '&')
+ return false;
+
+ if (previousNonWSChar == '=' || isCharImmediatelyPostReturn)
+ return true;
+
+ if (currentHeader == &AS_CATCH)
+ return true;
+
+ // get the last legal word (may be a number)
+ string lastWord = getPreviousWord(currentLine, charNum);
+ if (lastWord.empty())
+ lastWord[0] = ' ';
+ char nextChar = peekNextChar();
+
+ // check for preceding or following numeric values
+ if (isdigit(lastWord[0])
+ || isdigit(nextChar))
+ return false;
+
+ // checks on other chars
+ if (isLegalNameChar(lastWord[0])
+ && isLegalNameChar(nextChar)
+ && parenStack->back() > 0)
+ {
+ // if followed by an assignment it is a pointer or reference
+ size_t nextNum = currentLine.find_first_of("=;)", charNum + 1);
+ if (nextNum != string::npos && currentLine[nextNum] == '=')
+ return true;
+
+ // if a function definition it is a pointer or reference
+ // otherwise it is an arithmetic operator
+ if (!isBracketType(bracketTypeStack->back(), COMMAND_TYPE))
+ return true;
+ else
+ return false;
+ }
+
+ if (nextChar == '-'
+ || nextChar == '+')
+ {
+ size_t nextNum = currentLine.find_first_not_of(" \t", charNum + 1);
+ if (nextNum != string::npos)
+ {
+ if (currentLine.compare(nextNum, 2, "++") != 0
+ && currentLine.compare(nextNum, 2, "--") != 0)
+ return false;
+ }
+ }
+
+ bool isPR = (!isInPotentialCalculation
+ || isBracketType(bracketTypeStack->back(), DEFINITION_TYPE)
+ || (!isLegalNameChar(previousNonWSChar)
+ && !(previousNonWSChar == ')' && nextChar == '(')
+ && !(previousNonWSChar == ')' && currentChar == '*')
+ && previousNonWSChar != ']')
+ );
+
+ if (!isPR)
+ {
+ isPR |= (!isWhiteSpace(nextChar)
+ && nextChar != '-'
+ && nextChar != '('
+ && nextChar != '['
+ && !isLegalNameChar(nextChar));
+ }
+
+ return isPR;
+}
+
+/**
+ * Check if the currently reached '*' or '&' character is
+ * a dereferenced pointer or "address of" symbol.
+ * NOTE: this MUST be a pointer or reference as determined by
+ * the function isPointerOrReference().
+ *
+ * @return whether current character is a dereference or address of
+ */
+bool ASFormatter::isDereferenceOrAddressOf() const
+{
+ assert(isPointerOrReference());
+
+ if (previousNonWSChar == '='
+ || previousNonWSChar == ','
+ || previousNonWSChar == '.'
+ || previousNonWSChar == '>'
+ || previousNonWSChar == '<'
+ || isCharImmediatelyPostReturn)
+ return true;
+
+ // check for **
+ if (currentChar == '*'
+ && (int) currentLine.length() > charNum
+ && currentLine[charNum+1] == '*')
+ {
+ if (previousNonWSChar == '(')
+ return true;
+ if ((int) currentLine.length() < charNum + 2)
+ return true;
+ return false;
+ }
+
+ // check first char on the line
+ if (charNum == (int) currentLine.find_first_not_of(" \t"))
+ return true;
+
+ size_t nextChar = currentLine.find_first_not_of(" \t", charNum+1);
+ if (nextChar != string::npos
+ && (currentLine[nextChar] == ')'
+ || currentLine[nextChar] == '>'
+ || currentLine[nextChar] == ','))
+ return false;
+
+ string lastWord = getPreviousWord(currentLine, charNum);
+ if (lastWord == "else" || lastWord == "delete")
+ return true;
+
+ bool isDA = (!(isLegalNameChar(previousNonWSChar) || previousNonWSChar == '>')
+ || !isLegalNameChar(peekNextChar())
+ || (ispunct(previousNonWSChar) && previousNonWSChar != '.')
+ || isCharImmediatelyPostReturn);
+
+ return isDA;
+}
+
+/**
+ * Check if the currently reached '*' or '&' character is
+ * centered with one space on each side.
+ * Only spaces are checked, not tabs.
+ * If true then a space wil be deleted on the output.
+ *
+ * @return whether current character is centered.
+ */
+bool ASFormatter::isPointerOrReferenceCentered() const
+{
+ assert(currentLine[charNum] == '*' || currentLine[charNum] == '&');
+
+ int prNum = charNum;
+ int lineLength = (int) currentLine.length();
+ // check space before
+ if (prNum < 1
+ || currentLine[prNum-1] != ' ')
+ return false;
+
+ // check no space before that
+ if (prNum < 2
+ || currentLine[prNum-2] == ' ')
+ return false;
+
+ // check for **
+ if (prNum + 1 < lineLength
+ && currentLine[prNum+1] == '*')
+ prNum++;
+
+ // check space after
+ if (prNum + 1 < lineLength
+ && currentLine[prNum+1] != ' ')
+ return false;
+
+ // check no space after that
+ if (prNum + 2 < lineLength
+ && currentLine[prNum+2] == ' ')
+ return false;
+
+ return true;
+}
+
+/**
+ * check if the currently reached '+' or '-' character is a unary operator
+ * this method takes for granted that the current character
+ * is a '+' or '-'.
+ *
+ * @return whether the current '+' or '-' is a unary operator.
+ */
+bool ASFormatter::isUnaryOperator() const
+{
+ assert(currentChar == '+' || currentChar == '-');
+
+ return ((isCharImmediatelyPostReturn || !isLegalNameChar(previousCommandChar))
+ && previousCommandChar != '.'
+ && previousCommandChar != '\"'
+ && previousCommandChar != '\''
+ && previousCommandChar != ')'
+ && previousCommandChar != ']');
+}
+
+
+/**
+ * check if the currently reached '+' or '-' character is
+ * part of an exponent, i.e. 0.2E-5.
+ *
+ * this method takes for granted that the current character
+ * is a '+' or '-'.
+ *
+ * @return whether the current '+' or '-' is in an exponent.
+ */
+bool ASFormatter::isInExponent() const
+{
+ assert(currentChar == '+' || currentChar == '-');
+
+ int formattedLineLength = formattedLine.length();
+ if (formattedLineLength >= 2)
+ {
+ char prevPrevFormattedChar = formattedLine[formattedLineLength - 2];
+ char prevFormattedChar = formattedLine[formattedLineLength - 1];
+
+ return ((prevFormattedChar == 'e' || prevFormattedChar == 'E')
+ && (prevPrevFormattedChar == '.' || isdigit(prevPrevFormattedChar)));
+ }
+ else
+ return false;
+}
+
+/**
+ * check if an array bracket should NOT have an in-statement indent
+ *
+ * @return the array is non in-statement
+ */
+bool ASFormatter::isNonInStatementArrayBracket() const
+{
+ bool returnVal = false;
+ char nextChar = peekNextChar();
+ // if this opening bracket begins the line there will be no inStatement indent
+ if (currentLineBeginsWithBracket
+ && charNum == (int) currentLineFirstBracketNum
+ && nextChar != '}')
+ returnVal = true;
+ // if an opening bracket ends the line there will be no inStatement indent
+ if (isWhiteSpace(nextChar)
+ || isBeforeAnyLineEndComment(charNum)
+ || nextChar == '{')
+ returnVal = true;
+
+ // Java "new Type [] {...}" IS an inStatement indent
+ if (isJavaStyle() && previousNonWSChar == ']')
+ returnVal = false;
+
+ // trace
+ //if (isNonInStatementArray)
+ // cout << traceLineNumber << " " << 'x' << endl;
+ //else
+ // cout << traceLineNumber << " " << ' ' << endl
+
+ return returnVal;
+}
+
+/**
+ * check if a one-line bracket has been reached,
+ * i.e. if the currently reached '{' character is closed
+ * with a complimentry '}' elsewhere on the current line,
+ *.
+ * @return has a one-line bracket been reached?
+ */
+bool ASFormatter::isOneLineBlockReached(string& line, int startChar) const
+{
+ assert(line[startChar] == '{');
+
+ bool isInComment = false;
+ bool isInQuote = false;
+ int bracketCount = 1;
+ int lineLength = line.length();
+ char quoteChar = ' ';
+
+ for (int i = startChar + 1; i < lineLength; ++i)
+ {
+ char ch = line[i];
+
+ if (isInComment)
+ {
+ if (line.compare(i, 2, "*/") == 0)
+ {
+ isInComment = false;
+ ++i;
+ }
+ continue;
+ }
+
+ if (ch == '\\')
+ {
+ ++i;
+ continue;
+ }
+
+ if (isInQuote)
+ {
+ if (ch == quoteChar)
+ isInQuote = false;
+ continue;
+ }
+
+ if (ch == '"' || ch == '\'')
+ {
+ isInQuote = true;
+ quoteChar = ch;
+ continue;
+ }
+
+ if (line.compare(i, 2, "//") == 0)
+ break;
+
+ if (line.compare(i, 2, "/*") == 0)
+ {
+ isInComment = true;
+ ++i;
+ continue;
+ }
+
+ if (ch == '{')
+ ++bracketCount;
+ else if (ch == '}')
+ --bracketCount;
+
+ if (bracketCount == 0)
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * peek at the next word to determine if it is a C# non-paren header.
+ * will look ahead in the input file if necessary.
+ *
+ * @param char position on currentLine to start the search
+ * @return true if the next word is get or set.
+ */
+bool ASFormatter::isNextWordSharpNonParenHeader(int startChar) const
+{
+ // look ahead to find the next non-comment text
+ string nextText = peekNextText(currentLine.substr(startChar));
+ if (nextText.length() == 0)
+ return false;
+ if (nextText[0] == '[')
+ return true;
+ if (!isCharPotentialHeader(nextText, 0))
+ return false;
+ if (findKeyword(nextText, 0, AS_GET) || findKeyword(nextText, 0, AS_SET)
+ || findKeyword(nextText, 0, AS_ADD) || findKeyword(nextText, 0, AS_REMOVE))
+ return true;
+ return false;
+}
+
+/**
+ * peek at the next char to determine if it is an opening bracket.
+ * will look ahead in the input file if necessary.
+ * this determines a java static constructor.
+ *
+ * @param char position on currentLine to start the search
+ * @return true if the next word is an opening bracket.
+ */
+bool ASFormatter::isNextCharOpeningBracket(int startChar) const
+{
+ bool retVal = false;
+ string nextText = peekNextText(currentLine.substr(startChar));
+ if (nextText.compare(0, 1, "{") == 0)
+ retVal = true;
+ return retVal;
+}
+
+/**
+ * get the next non-whitespace substring on following lines, bypassing all comments.
+ *
+ * @param the first line to check
+ * @return the next non-whitespace substring.
+ */
+string ASFormatter::peekNextText(const string& firstLine, bool endOnEmptyLine /*false*/) const
+{
+ bool isFirstLine = true;
+ bool needReset = false;
+ string nextLine = firstLine;
+ size_t firstChar= string::npos;
+
+ // find the first non-blank text, bypassing all comments.
+ bool isInComment = false;
+ while (sourceIterator->hasMoreLines())
+ {
+ if (isFirstLine)
+ isFirstLine = false;
+ else
+ {
+ nextLine = sourceIterator->peekNextLine();
+ needReset = true;
+ }
+
+ firstChar = nextLine.find_first_not_of(" \t");
+ if (firstChar == string::npos)
+ {
+ if (endOnEmptyLine && !isInComment)
+ break;
+ continue;
+ }
+
+ if (nextLine.compare(firstChar, 2, "/*") == 0)
+ isInComment = true;
+
+ if (isInComment)
+ {
+ firstChar = nextLine.find("*/", firstChar);
+ if (firstChar == string::npos)
+ continue;
+ firstChar += 2;
+ isInComment = false;
+ firstChar = nextLine.find_first_not_of(" \t", firstChar);
+ if (firstChar == string::npos)
+ continue;
+ }
+
+ if (nextLine.compare(firstChar, 2, "//") == 0)
+ continue;
+
+ // found the next text
+ break;
+ }
+
+ if (needReset)
+ sourceIterator->peekReset();
+ if (firstChar == string::npos)
+ nextLine = "";
+ else
+ nextLine = nextLine.substr(firstChar);
+ return nextLine;
+}
+
+/**
+ * adjust comment position because of adding or deleting spaces
+ * the spaces are added or deleted to formattedLine
+ * spacePadNum contains the adjustment
+ */
+void ASFormatter::adjustComments(void)
+{
+ assert(spacePadNum != 0);
+ assert(currentLine.compare(charNum, 2, "//") == 0
+ || currentLine.compare(charNum, 2, "/*") == 0);
+
+
+ // block comment must be closed on this line with nothing after it
+ if (currentLine.compare(charNum, 2, "/*") == 0)
+ {
+ size_t endNum = currentLine.find("*/", charNum + 2);
+ if (endNum == string::npos)
+ return;
+ if (currentLine.find_first_not_of(" \t", endNum + 2) != string::npos)
+ return;
+ }
+
+ size_t len = formattedLine.length();
+ // don't adjust a tab
+ if (formattedLine[len-1] == '\t')
+ return;
+ // if spaces were removed, need to add spaces before the comment
+ if (spacePadNum < 0)
+ {
+ int adjust = -spacePadNum; // make the number positive
+ formattedLine.append(adjust, ' ');
+ }
+ // if spaces were added, need to delete extra spaces before the comment
+ // if cannot be done put the comment one space after the last text
+ else if (spacePadNum > 0)
+ {
+ int adjust = spacePadNum;
+ size_t lastText = formattedLine.find_last_not_of(' ');
+ if (lastText != string::npos
+ && lastText < len - adjust - 1)
+ formattedLine.resize(len - adjust);
+ else if (len > lastText + 2)
+ formattedLine.resize(lastText + 2);
+ else if (len < lastText + 2)
+ formattedLine.append(len - lastText, ' ');
+ }
+}
+
+/**
+ * append the current bracket inside the end of line comments
+ * currentChar contains the bracket, it will be appended to formattedLine
+ * formattedLineCommentNum is the comment location on formattedLine
+ * returns true f appended, false if not
+ */
+void ASFormatter::appendCharInsideComments(void)
+{
+ if (formattedLineCommentNum == string::npos) // does the comment start on the previous line?
+ {
+ appendCurrentChar(); // don't attach
+ return; // false;
+ }
+ assert(formattedLine.compare(formattedLineCommentNum, 2, "//") == 0
+ || formattedLine.compare(formattedLineCommentNum, 2, "/*") == 0);
+
+ // find the previous non space char
+ size_t end = formattedLineCommentNum;
+ size_t beg = formattedLine.find_last_not_of(" \t", end-1);
+ if (beg == string::npos) // is the previous line comment only?
+ {
+ appendCurrentChar(); // don't attach
+ return; // false;
+ }
+ beg++;
+
+ // insert the bracket
+ if (end - beg < 3) // is there room to insert?
+ formattedLine.insert(beg, 3-end+beg, ' ');
+ if (formattedLine[beg] == '\t') // don't pad with a tab
+ formattedLine.insert(beg, 1, ' ');
+ formattedLine[beg+1] = currentChar;
+
+ if (isBeforeComment())
+ breakLine();
+ else if (isCharImmediatelyPostLineComment)
+ shouldBreakLineAtNextChar = true;
+ return; // true;
+}
+
+/**
+ * add or remove space padding to operators
+ * currentChar contains the paren
+ * the operators and necessary padding will be appended to formattedLine
+ * the calling function should have a continue statement after calling this method
+ *
+ * @param *newOperator the operator to be padded
+ */
+void ASFormatter::padOperators(const string *newOperator)
+{
+ assert(newOperator != NULL);
+
+ bool shouldPad = (newOperator != &AS_COLON_COLON
+ && newOperator != &AS_PAREN_PAREN
+ && newOperator != &AS_BLPAREN_BLPAREN
+ && newOperator != &AS_PLUS_PLUS
+ && newOperator != &AS_MINUS_MINUS
+ && newOperator != &AS_NOT
+ && newOperator != &AS_BIT_NOT
+ && newOperator != &AS_ARROW
+ && !(newOperator == &AS_MINUS && isInExponent())
+ && !((newOperator == &AS_PLUS || newOperator == &AS_MINUS) // check for unary plus or minus
+ && (previousNonWSChar == '('
+ || previousNonWSChar == '='
+ || previousNonWSChar == ','))
+ && !(newOperator == &AS_PLUS && isInExponent())
+ && !isCharImmediatelyPostOperator
+ && !((newOperator == &AS_MULT || newOperator == &AS_BIT_AND)
+ && isPointerOrReference())
+ && !(newOperator == &AS_MULT
+ && (previousNonWSChar == '.'
+ || previousNonWSChar == '>')) // check for ->
+ && !((isInTemplate || isCharImmediatelyPostTemplate)
+ && (newOperator == &AS_LS || newOperator == &AS_GR))
+ && !(newOperator == &AS_GCC_MIN_ASSIGN
+ && ASBase::peekNextChar(currentLine, charNum+1) == '>')
+ && !(newOperator == &AS_GR && previousNonWSChar == '?')
+ && !isInCase
+ && !isInAsm
+ && !isInAsmOneLine
+ && !isInAsmBlock
+ );
+
+ // pad before operator
+ if (shouldPad
+ && !isInBlParen
+ && !(newOperator == &AS_COLON && !foundQuestionMark)
+ && !(newOperator == &AS_QUESTION && isSharpStyle() // check for C# nullable type (e.g. int?)
+ && currentLine.find(':', charNum+1) == string::npos)
+ )
+ appendSpacePad();
+ appendSequence(*newOperator);
+ goForward(newOperator->length() - 1);
+
+ // since this block handles '()' and '[]',
+ // the parenStack must be updated here accordingly!
+ if (newOperator == &AS_PAREN_PAREN
+ || newOperator == &AS_BLPAREN_BLPAREN)
+ parenStack->back()--;
+
+ currentChar = (*newOperator)[newOperator->length() - 1];
+ // pad after operator
+ // but do not pad after a '-' that is a unary-minus.
+ if (shouldPad
+ && !isInBlParen
+ && !isBeforeAnyComment()
+ && !(newOperator == &AS_PLUS && isUnaryOperator())
+ && !(newOperator == &AS_MINUS && isUnaryOperator())
+ && !(currentLine.compare(charNum + 1, 1, ";") == 0)
+ && !(currentLine.compare(charNum + 1, 2, "::") == 0)
+ && !(newOperator == &AS_QUESTION && isSharpStyle() // check for C# nullable type (e.g. int?)
+ && currentLine[charNum+1] == '[')
+ )
+ appendSpaceAfter();
+
+ previousOperator = newOperator;
+ return;
+}
+
+/**
+ * format pointer or reference
+ * currentChar contains the pointer or reference
+ * the symbol and necessary padding will be appended to formattedLine
+ * the calling function should have a continue statement after calling this method
+ */
+void ASFormatter::formatPointerOrReference(void)
+{
+ assert(currentChar == '*' || currentChar == '&');
+ assert(isCStyle());
+
+ // check for cast
+ char peekedChar = peekNextChar();
+ if (currentChar == '*'
+ && (int) currentLine.length() > charNum
+ && currentLine[charNum+1] == '*')
+ {
+ size_t nextChar = currentLine.find_first_not_of(" \t", charNum+2);
+ if (nextChar == string::npos)
+ peekedChar = ' ';
+ else
+ peekedChar = currentLine[nextChar];
+ }
+ if (peekedChar == ')' || peekedChar =='>' || peekedChar ==',')
+ {
+ formatPointerOrReferenceCast();
+ return;
+ }
+
+ // do this before bumping charNum
+ bool isOldPRCentered = isPointerOrReferenceCentered();
+
+ if (pointerAlignment == ALIGN_TYPE)
+ {
+ size_t prevCh = formattedLine.find_last_not_of(" \t");
+ if (prevCh == string::npos)
+ prevCh = 0;
+ if (formattedLine.length() == 0 || prevCh == formattedLine.length() - 1)
+ appendCurrentChar();
+ else
+ {
+ // exchange * or & with character following the type
+ // this may not work every time with a tab character
+ string charSave = formattedLine.substr(prevCh+1, 1);
+ formattedLine[prevCh+1] = currentChar;
+ formattedLine.append(charSave);
+ }
+ if (isSequenceReached("**"))
+ {
+ formattedLine.insert(prevCh+2, "*");
+ goForward(1);
+ }
+ // if no space after * then add one
+ if (charNum < (int) currentLine.length() - 1
+ && !isWhiteSpace(currentLine[charNum+1])
+ && currentLine[charNum+1] != ')')
+ appendSpacePad();
+ // if old pointer or reference is centered, remove a space
+ if (isOldPRCentered
+ && isWhiteSpace(formattedLine[formattedLine.length()-1]))
+ {
+ formattedLine.erase(formattedLine.length()-1, 1);
+ spacePadNum--;
+ }
+ }
+ else if (pointerAlignment == ALIGN_MIDDLE)
+ {
+ // compute current whitespace before
+ size_t wsBefore = currentLine.find_last_not_of(" \t", charNum - 1);
+ if (wsBefore == string::npos)
+ wsBefore = 0;
+ else
+ wsBefore = charNum - wsBefore - 1;
+ // adjust for **
+ string sequenceToInsert = currentChar == '*' ? "*" : "&";
+ if (isSequenceReached("**"))
+ {
+ sequenceToInsert = "**";
+ goForward(1);
+ }
+ size_t charNumSave = charNum;
+ // goForward() to convert tabs to spaces, if necessary,
+ // and move following characters to preceding characters
+ // this may not work every time with tab characters
+ for (size_t i = charNum+1; i < currentLine.length() && isWhiteSpace(currentLine[i]); i++)
+ {
+ goForward(1);
+ formattedLine.append(1, currentLine[i]);
+ }
+ // whitespace should be at least 2 chars
+ size_t wsAfter = currentLine.find_first_not_of(" \t", charNumSave + 1);
+ if (wsAfter == string::npos)
+ wsAfter = 0;
+ else
+ wsAfter = wsAfter - charNumSave - 1;
+ if (wsBefore + wsAfter < 2)
+ {
+ size_t charsToAppend = (2 - (wsBefore + wsAfter));
+ formattedLine.append(charsToAppend, ' ');
+ spacePadNum += charsToAppend;
+ if (wsBefore == 0) wsBefore++;
+ if (wsAfter == 0) wsAfter++;
+ }
+ // insert the pointer or reference char
+ size_t padAfter = (wsBefore + wsAfter) / 2;
+ formattedLine.insert(formattedLine.length() - padAfter, sequenceToInsert);
+ }
+ else if (pointerAlignment == ALIGN_NAME)
+ {
+ size_t startNum = formattedLine.find_last_not_of(" \t");
+ string sequenceToInsert = currentChar == '*' ? "*" : "&";
+ if (isSequenceReached("**"))
+ {
+ sequenceToInsert = "**";
+ goForward(1);
+ }
+ // goForward() to convert tabs to spaces, if necessary,
+ // and move following characters to preceding characters
+ // this may not work every time with tab characters
+ for (size_t i = charNum+1; i < currentLine.length() && isWhiteSpace(currentLine[i]); i++)
+ {
+ goForward(1);
+ formattedLine.append(1, currentLine[i]);
+ }
+ appendSequence(sequenceToInsert, false);
+ // if no space before * then add one
+ if (startNum != string::npos
+ && !isWhiteSpace(formattedLine[startNum+1]))
+ {
+ formattedLine.insert(startNum+1 , 1, ' ');
+ spacePadNum++;
+ }
+ // if old pointer or reference is centered, remove a space
+ if (isOldPRCentered
+ && formattedLine.length() > startNum+1
+ && isWhiteSpace(formattedLine[startNum+1]))
+ {
+ formattedLine.erase(startNum+1, 1);
+ spacePadNum--;
+ }
+ }
+ else // pointerAlignment == ALIGN_NONE
+ {
+ appendCurrentChar();
+ }
+ return;
+}
+
+/**
+ * format pointer or reference cast
+ * currentChar contains the pointer or reference
+ * NOTE: the pointers and references in function definitions
+ * are processed as a cast (e.g. void foo(void*, void*))
+ * is processed here.
+ */
+void ASFormatter::formatPointerOrReferenceCast(void)
+{
+ assert(currentChar == '*' || currentChar == '&');
+ assert(isCStyle());
+
+ string sequenceToInsert = currentChar == '*' ? "*" : "&";
+ if (isSequenceReached("**"))
+ {
+ sequenceToInsert = "**";
+ goForward(1);
+ }
+ if (pointerAlignment == ALIGN_NONE)
+ {
+ appendSequence(sequenceToInsert, false);
+ return;
+ }
+ // remove trailing whitespace
+ size_t prevCh = formattedLine.find_last_not_of(" \t");
+ if (prevCh == string::npos)
+ prevCh = 0;
+ if (formattedLine.length() > 0 && isWhiteSpace(formattedLine[prevCh+1]))
+ {
+ spacePadNum -= (formattedLine.length() - 1 - prevCh);
+ formattedLine.erase(prevCh+1);
+ }
+ if (pointerAlignment == ALIGN_TYPE)
+ {
+ appendSequence(sequenceToInsert, false);
+ }
+ else if (pointerAlignment == ALIGN_MIDDLE
+ || pointerAlignment == ALIGN_NAME)
+ {
+ appendSpacePad();
+ appendSequence(sequenceToInsert, false);
+ }
+ else
+ appendSequence(sequenceToInsert, false);
+}
+
+/**
+ * add or remove space padding to parens
+ * currentChar contains the paren
+ * the parens and necessary padding will be appended to formattedLine
+ * the calling function should have a continue statement after calling this method
+ */
+void ASFormatter::padParens(void)
+{
+ assert(currentChar == '(' || currentChar == ')');
+
+ int spacesOutsideToDelete = 0;
+ int spacesInsideToDelete = 0;
+
+ if (currentChar == '(')
+ {
+ spacesOutsideToDelete = formattedLine.length() - 1;
+ spacesInsideToDelete = 0;
+
+ // compute spaces outside the opening paren to delete
+ if (shouldUnPadParens)
+ {
+ char lastChar = ' ';
+ bool prevIsParenHeader = false;
+ size_t i = formattedLine.find_last_not_of(" \t");
+ if (i != string::npos)
+ {
+ // if last char is a bracket the previous whitespace is an indent
+ if (formattedLine[i] == '{')
+ spacesOutsideToDelete = 0;
+ else
+ {
+ spacesOutsideToDelete -= i;
+ lastChar = formattedLine[i];
+ // if previous word is a header, it will be a paren header
+ string prevWord = getPreviousWord(formattedLine, formattedLine.length());
+ const string* prevWordH = NULL;
+ if (shouldPadHeader
+ && prevWord.length() > 0
+ && isCharPotentialHeader(prevWord, 0))
+ prevWordH = ASBeautifier::findHeader(prevWord, 0, headers);
+ if (prevWordH != NULL)
+ {
+ prevIsParenHeader = true;
+ // trace
+ //cout << traceLineNumber << " " << *prevWordH << endl;
+ }
+ else if (prevWord == "return" // don't unpad return statements
+ || prevWord == "*") // don't unpad multiply or pointer
+ {
+ prevIsParenHeader = true;
+ // trace
+ //cout << traceLineNumber << " " << prevWord << endl;
+ }
+ // don't unpad variables
+ else if (prevWord == "bool"
+ || prevWord == "int"
+ || prevWord == "void"
+ || prevWord == "void*"
+ || (prevWord.length() >= 6 // check end of word for _t
+ && prevWord.compare(prevWord.length()-2, 2, "_t") == 0)
+ || prevWord == "BOOL"
+ || prevWord == "DWORD"
+ || prevWord == "HWND"
+ || prevWord == "INT"
+ || prevWord == "LPSTR"
+ || prevWord == "VOID"
+ || prevWord == "LPVOID"
+ )
+ {
+ prevIsParenHeader = true;
+ // trace
+ //cout << traceLineNumber << " " << prevWord << endl;
+ }
+ }
+ }
+ // do not unpad operators, but leave them if already padded
+ if (shouldPadParensOutside || prevIsParenHeader)
+ spacesOutsideToDelete--;
+ else if (lastChar == '|' // check for ||
+ || lastChar == '&' // check for &&
+ || lastChar == ','
+ || (lastChar == '>' && !foundCastOperator)
+ || lastChar == '<'
+ || lastChar == '?'
+ || lastChar == ':'
+ || lastChar == ';'
+ || lastChar == '='
+ || lastChar == '+'
+ || lastChar == '-'
+ || (lastChar == '*' && isInPotentialCalculation)
+ || lastChar == '/'
+ || lastChar == '%')
+ spacesOutsideToDelete--;
+
+ if (spacesOutsideToDelete > 0)
+ {
+ formattedLine.erase(i + 1, spacesOutsideToDelete);
+ spacePadNum -= spacesOutsideToDelete;
+ }
+ }
+
+ // pad open paren outside
+ char peekedCharOutside = peekNextChar();
+ if (shouldPadParensOutside)
+ if (!(currentChar == '(' && peekedCharOutside == ')'))
+ appendSpacePad();
+
+ appendCurrentChar();
+
+ // unpad open paren inside
+ if (shouldUnPadParens)
+ {
+ size_t j = currentLine.find_first_not_of(" \t", charNum + 1);
+ if (j != string::npos)
+ spacesInsideToDelete = j - charNum - 1;
+ if (shouldPadParensInside)
+ spacesInsideToDelete--;
+ if (spacesInsideToDelete > 0)
+ {
+ currentLine.erase(charNum + 1, spacesInsideToDelete);
+ spacePadNum -= spacesInsideToDelete;
+ }
+ // convert tab to space if requested
+ if (shouldConvertTabs
+ && (int)currentLine.length() > charNum
+ && currentLine[charNum+1] == '\t')
+ currentLine[charNum+1] = ' ';
+
+ }
+
+ // pad open paren inside
+ char peekedCharInside = peekNextChar();
+ if (shouldPadParensInside)
+ if (!(currentChar == '(' && peekedCharInside == ')'))
+ appendSpaceAfter();
+ // trace
+ //if(spacesOutsideToDelete > 0 || spacesInsideToDelete > 0)
+ // cout << traceLineNumber << " " << spacesOutsideToDelete << '(' << spacesInsideToDelete << endl;
+ }
+ else if (currentChar == ')' /*|| currentChar == ']'*/)
+ {
+ spacesOutsideToDelete = 0;
+ spacesInsideToDelete = formattedLine.length();
+
+ // unpad close paren inside
+ if (shouldUnPadParens)
+ {
+ size_t i = formattedLine.find_last_not_of(" \t");
+ if (i != string::npos)
+ spacesInsideToDelete = formattedLine.length() - 1 - i;
+ if (shouldPadParensInside)
+ spacesInsideToDelete--;
+ if (spacesInsideToDelete > 0)
+ {
+ formattedLine.erase(i + 1, spacesInsideToDelete);
+ spacePadNum -= spacesInsideToDelete;
+ }
+ }
+
+ // pad close paren inside
+ if (shouldPadParensInside)
+ if (!(previousChar == '(' && currentChar == ')'))
+ appendSpacePad();
+
+ appendCurrentChar();
+
+ // unpad close paren outside
+ if (shouldUnPadParens)
+ {
+ // may have end of line comments
+ size_t j = currentLine.find_first_not_of(" \t", charNum + 1);
+ if (j != string::npos)
+ if (currentLine[j] == '[' || currentLine[j] == ']')
+ spacesOutsideToDelete = j - charNum - 1;
+ if (shouldPadParensOutside)
+ spacesOutsideToDelete--;
+
+ if (spacesOutsideToDelete > 0)
+ {
+ currentLine.erase(charNum + 1, spacesOutsideToDelete);
+ spacePadNum -= spacesOutsideToDelete;
+ }
+ }
+
+ // pad close paren outside
+ char peekedCharOutside = peekNextChar();
+ if (shouldPadParensOutside)
+ if (peekedCharOutside != ';'
+ && peekedCharOutside != ','
+ && peekedCharOutside != '.'
+ && peekedCharOutside != '-') // check for ->
+ appendSpaceAfter();
+
+ // trace
+ //if(spacesInsideToDelete > 0)
+ // cout << traceLineNumber << " " << spacesInsideToDelete << ')' << 0 << endl;
+ }
+ return;
+}
+
+/**
+ * format opening bracket as attached or broken
+ * currentChar contains the bracket
+ * the brackets will be appended to the current formattedLine or a new formattedLine as necessary
+ * the calling function should have a continue statement after calling this method
+ *
+ * @param bracketType the type of bracket to be formatted.
+ */
+void ASFormatter::formatOpeningBracket(BracketType bracketType)
+{
+ assert(!isBracketType(bracketType, ARRAY_TYPE));
+ assert(currentChar == '{');
+
+ parenStack->push_back(0);
+
+ bool breakBracket = isCurrentBracketBroken();
+
+ if (breakBracket)
+ {
+ if (isBeforeAnyComment() && isOkToBreakBlock(bracketType))
+ {
+ // if comment is at line end leave the comment on this line
+ if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket) // lineBeginsWith('{')
+ {
+ currentChar = ' '; // remove bracket from current line
+ currentLine[charNum] = currentChar;
+ appendOpeningBracket = true; // append bracket to following line
+ }
+ // else put comment after the bracket
+ else if (!isBeforeMultipleLineEndComments(charNum))
+ breakLine();
+ }
+ else if (!isBracketType(bracketType, SINGLE_LINE_TYPE))
+ breakLine();
+ else if (shouldBreakOneLineBlocks && peekNextChar() != '}')
+ breakLine();
+ else if (!isInLineBreak)
+ appendSpacePad();
+
+ appendCurrentChar();
+
+ // should a following comment break from the bracket?
+ // must break the line AFTER the bracket
+ if (isBeforeComment()
+ && formattedLine[0] == '{'
+ && isOkToBreakBlock(bracketType)
+ && (bracketFormatMode == BREAK_MODE
+ || bracketFormatMode == LINUX_MODE
+ || bracketFormatMode == STROUSTRUP_MODE))
+ {
+ shouldBreakLineAtNextChar = true;
+ }
+
+ }
+ else // attach bracket
+ {
+ // are there comments before the bracket?
+ if (isCharImmediatelyPostComment || isCharImmediatelyPostLineComment)
+ {
+ if (isOkToBreakBlock(bracketType)
+ && !(isCharImmediatelyPostComment && isCharImmediatelyPostLineComment) // don't attach if two comments on the line
+ && peekNextChar() != '}' // don't attach { }
+ && previousCommandChar != '{' // don't attach { {
+ && previousCommandChar != '}' // don't attach } {
+ && previousCommandChar != ';') // don't attach ; {
+ {
+ appendCharInsideComments();
+ }
+ else
+ {
+ appendCurrentChar(); // don't attach
+ }
+ }
+ else if (previousCommandChar == '{'
+ || previousCommandChar == '}'
+ || previousCommandChar == ';') // '}' , ';' chars added for proper handling of '{' immediately after a '}' or ';'
+ {
+ appendCurrentChar(); // don't attach
+ }
+ else
+ {
+ // if a blank line preceeds this don't attach
+ if (isEmptyLine(formattedLine))
+ appendCurrentChar(); // don't attach
+ else if (isOkToBreakBlock(bracketType)
+ && !(isImmediatelyPostPreprocessor
+ && currentLineBeginsWithBracket)) // lineBeginsWith('{')
+ {
+ if (peekNextChar() != '}')
+ {
+ appendSpacePad();
+ appendCurrentChar(false); // OK to attach
+ // should a following comment attach with the bracket?
+ // insert spaces to reposition the comment
+ if (isBeforeComment()
+ && !isBeforeMultipleLineEndComments(charNum)
+ && (!isBeforeAnyLineEndComment(charNum) || currentLineBeginsWithBracket)) // lineBeginsWith('{')
+ {
+ breakLine();
+ currentLine.insert(charNum+1, charNum+1, ' ');
+ }
+ }
+ else
+ {
+ appendSpacePad();
+ appendCurrentChar();
+ }
+ }
+ else
+ {
+ if (!isInLineBreak)
+ appendSpacePad();
+ appendCurrentChar(); // don't attach
+ }
+ }
+ }
+}
+
+/**
+ * format closing bracket
+ * currentChar contains the bracket
+ * the calling function should have a continue statement after calling this method
+ *
+ * @param bracketType the type of bracket to be formatted.
+ */
+void ASFormatter::formatClosingBracket(BracketType bracketType)
+{
+ assert(!isBracketType(bracketType, ARRAY_TYPE));
+ assert(currentChar == '}');
+
+ // parenStack must contain one entry
+ if (parenStack->size() > 1)
+ parenStack->pop_back();
+
+ // mark state of immediately after empty block
+ // this state will be used for locating brackets that appear immedately AFTER an empty block (e.g. '{} \n}').
+ if (previousCommandChar == '{')
+ isImmediatelyPostEmptyBlock = true;
+
+ if ((!(previousCommandChar == '{' && isPreviousBracketBlockRelated)) // this '{' does not close an empty block
+ && isOkToBreakBlock(bracketType) // astyle is allowed to break on line blocks
+ && !isImmediatelyPostEmptyBlock) // this '}' does not immediately follow an empty block
+ {
+ breakLine();
+ appendCurrentChar();
+ }
+ else
+ {
+ appendCurrentChar();
+ }
+
+ // if a declaration follows a definition, space pad
+ if (isLegalNameChar(peekNextChar()))
+ appendSpaceAfter();
+
+ if (shouldBreakBlocks && currentHeader != NULL && parenStack->back() == 0)
+ {
+ isAppendPostBlockEmptyLineRequested = true;
+ }
+}
+
+/**
+ * format array brackets as attached or broken
+ * determine if the brackets can have an inStatement indent
+ * currentChar contains the bracket
+ * the brackets will be appended to the current formattedLine or a new formattedLine as necessary
+ * the calling function should have a continue statement after calling this method
+ *
+ * @param bracketType the type of bracket to be formatted, must be an ARRAY_TYPE.
+ * @param isOpeningArrayBracket indicates if this is the opening bracket for the array block.
+ */
+void ASFormatter::formatArrayBrackets(BracketType bracketType, bool isOpeningArrayBracket)
+{
+ assert(isBracketType(bracketType, ARRAY_TYPE));
+ assert(currentChar == '{' || currentChar == '}');
+
+ if (currentChar == '{')
+ {
+ // is this the first opening bracket in the array?
+ if (isOpeningArrayBracket)
+ {
+ if (bracketFormatMode == ATTACH_MODE
+ || bracketFormatMode == LINUX_MODE
+ || bracketFormatMode == STROUSTRUP_MODE)
+ {
+ // don't attach to a preprocessor directive
+ if (isImmediatelyPostPreprocessor && currentLineBeginsWithBracket) // lineBeginsWith('{')
+ {
+ isInLineBreak = true;
+ appendCurrentChar(); // don't attach
+ }
+ else if (isCharImmediatelyPostComment)
+ {
+ // TODO: attach bracket to line-end comment
+ appendCurrentChar(); // don't attach
+ }
+ else if (isCharImmediatelyPostLineComment)
+ {
+ appendCharInsideComments();
+ }
+ else
+ {
+ // if a blank line preceeds this don't attach
+ if (isEmptyLine(formattedLine))
+ appendCurrentChar(); // don't attach
+ else
+ {
+ // if bracket is broken or not an assignment
+ if (currentLineBeginsWithBracket // lineBeginsWith('{')
+ && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE))
+ {
+ appendSpacePad();
+ appendCurrentChar(false); // OK to attach
+
+ if (currentLineBeginsWithBracket
+ && (int)currentLineFirstBracketNum == charNum)
+ shouldBreakLineAtNextChar = true;
+ }
+ else
+ {
+ appendSpacePad();
+ appendCurrentChar();
+ }
+ }
+ }
+ }
+ else if (bracketFormatMode == BREAK_MODE)
+ {
+ if (isWhiteSpace(peekNextChar()))
+ breakLine();
+ else if (isBeforeAnyComment())
+ {
+ // do not break unless comment is at line end
+ if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket)
+ {
+ currentChar = ' '; // remove bracket from current line
+ appendOpeningBracket = true; // append bracket to following line
+ }
+ }
+ if (!isInLineBreak)
+ appendSpacePad();
+ appendCurrentChar();
+
+ if (currentLineBeginsWithBracket
+ && (int)currentLineFirstBracketNum == charNum
+ && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE))
+ shouldBreakLineAtNextChar = true;
+ }
+ else if (bracketFormatMode == HORSTMANN_MODE)
+ {
+ if (isWhiteSpace(peekNextChar()))
+ breakLine();
+ else if (isBeforeAnyComment())
+ {
+ // do not break unless comment is at line end
+ if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket) // lineBeginsWith('{')
+ {
+ currentChar = ' '; // remove bracket from current line
+ appendOpeningBracket = true; // append bracket to following line
+ }
+ }
+ if (!isInLineBreak)
+ appendSpacePad();
+ appendCurrentChar();
+ }
+ else if (bracketFormatMode == NONE_MODE)
+ {
+ if (currentLineBeginsWithBracket) // lineBeginsWith('{')
+ {
+ appendCurrentChar(); // don't attach
+ }
+ else
+ {
+ appendSpacePad();
+ appendCurrentChar(false); // OK to attach
+ }
+ }
+ }
+ else // not the first opening bracket
+ {
+ if (bracketFormatMode == HORSTMANN_MODE)
+ {
+ if (previousNonWSChar == '{'
+ && bracketTypeStack->size() > 2
+ && !isBracketType((*bracketTypeStack)[bracketTypeStack->size()-2], SINGLE_LINE_TYPE))
+ formatArrayRunIn();
+ }
+ else if (!isInLineBreak
+ && !isWhiteSpace(peekNextChar())
+ && previousNonWSChar == '{'
+ && bracketTypeStack->size() > 2
+ && !isBracketType((*bracketTypeStack)[bracketTypeStack->size()-2], SINGLE_LINE_TYPE))
+ formatArrayRunIn();
+
+ appendCurrentChar();
+ }
+ }
+ else if (currentChar == '}')
+ {
+ // does this close the first opening bracket in the array?
+ if (!isBracketType(bracketType, SINGLE_LINE_TYPE) )
+ breakLine();
+ appendCurrentChar();
+
+ // if a declaration follows an enum definition, space pad
+ char peekedChar = peekNextChar();
+ if (isLegalNameChar(peekedChar)
+ || peekedChar == '[')
+ appendSpaceAfter();
+ }
+}
+
+/**
+ * determine if a run-in can be attached.
+ * if it can insert the indents in formattedLine and reset the current line break.
+ */
+void ASFormatter::formatRunIn()
+{
+ assert(bracketFormatMode == HORSTMANN_MODE || bracketFormatMode == NONE_MODE);
+
+ // keep one line blocks returns true without indenting the run-in
+ if (!isOkToBreakBlock(bracketTypeStack->back()))
+ return; // true;
+
+ size_t lastText = formattedLine.find_last_not_of(" \t");
+ if (lastText == string::npos || formattedLine[lastText] != '{')
+ return; // false;
+
+ // make sure the bracket is broken
+ if (formattedLine.find_first_not_of(" \t{") != string::npos)
+ return; // false;
+
+ if (isBracketType(bracketTypeStack->back(), NAMESPACE_TYPE))
+ return; // false;
+
+ bool extraIndent = false;
+ isInLineBreak = true;
+
+ // cannot attach a class modifier without indent-classes
+ if (isCStyle()
+ && isCharPotentialHeader(currentLine, charNum)
+ && (isBracketType(bracketTypeStack->back(), CLASS_TYPE)
+ || (isBracketType(bracketTypeStack->back(), STRUCT_TYPE)
+ && isInIndentableStruct)))
+ {
+ if (findKeyword(currentLine, charNum, AS_PUBLIC)
+ || findKeyword(currentLine, charNum, AS_PRIVATE)
+ || findKeyword(currentLine, charNum, AS_PROTECTED))
+ {
+ if (!getClassIndent())
+ return; // false;
+ }
+ else if (getClassIndent())
+ extraIndent = true;
+ }
+
+ // cannot attach a 'case' statement without indent-switches
+ if (!getSwitchIndent()
+ && isCharPotentialHeader(currentLine, charNum)
+ && (findKeyword(currentLine, charNum, AS_CASE)
+ || findKeyword(currentLine, charNum, AS_DEFAULT)))
+ return; // false;
+
+ // extra indent for switch statements
+ if (getSwitchIndent()
+ && !preBracketHeaderStack->empty()
+ && preBracketHeaderStack->back() == &AS_SWITCH
+ && ((isLegalNameChar(currentChar)
+ && !findKeyword(currentLine, charNum, AS_CASE))
+ || isSequenceReached("//")
+ || isSequenceReached("/*")))
+ extraIndent = true;
+
+ isInLineBreak = false;
+ // remove for extra whitespace
+ if (formattedLine.length() > lastText+1
+ && formattedLine.find_first_not_of(" \t", lastText+1) == string::npos)
+ formattedLine.erase(lastText+1);
+
+ if (getIndentString() == "\t")
+ {
+ appendChar('\t', false);
+ horstmannIndentChars = 2; // one for { and one for tab
+ if (extraIndent)
+ {
+ appendChar('\t', false);
+ horstmannIndentChars++;
+ }
+ }
+ else
+ {
+ int indent = getIndentLength();
+ formattedLine.append(indent-1, ' ');
+ horstmannIndentChars = indent;
+ if (extraIndent)
+ {
+ formattedLine.append(indent, ' ');
+ horstmannIndentChars += indent;
+ }
+ }
+ isInHorstmannRunIn = true;
+}
+
+/**
+ * remove whitepace and add indentation for an array run-in.
+ */
+void ASFormatter::formatArrayRunIn()
+{
+ assert(isBracketType(bracketTypeStack->back(), ARRAY_TYPE));
+
+ // make sure the bracket is broken
+ if (formattedLine.find_first_not_of(" \t{") != string::npos)
+ return;
+
+ size_t lastText = formattedLine.find_last_not_of(" \t");
+ if (lastText == string::npos || formattedLine[lastText] != '{')
+ return;
+
+ // check for extra whitespace
+ if (formattedLine.length() > lastText+1
+ && formattedLine.find_first_not_of(" \t", lastText+1) == string::npos)
+ formattedLine.erase(lastText+1);
+
+ if (getIndentString() == "\t")
+ {
+ appendChar('\t', false);
+ horstmannIndentChars = 2; // one for { and one for tab
+ }
+ else
+ {
+ int indent = getIndentLength();
+ formattedLine.append(indent-1, ' ');
+ horstmannIndentChars = indent;
+ }
+ isInHorstmannRunIn = true;
+ isInLineBreak = false;
+}
+
+/**
+ * delete a bracketTypeStack vector object
+ * BracketTypeStack did not work with the DeleteContainer template
+ */
+void ASFormatter::deleteContainer(vector<BracketType>* &container)
+{
+ if (container != NULL)
+ {
+ container->clear();
+ delete (container);
+ container = NULL;
+ }
+}
+
+/**
+ * delete a vector object
+ * T is the type of vector
+ * used for all vectors except bracketTypeStack
+ */
+template<typename T>
+void ASFormatter::deleteContainer(T &container)
+{
+ if (container != NULL)
+ {
+ container->clear();
+ delete (container);
+ container = NULL;
+ }
+}
+
+/**
+ * initialize a BracketType vector object
+ * BracketType did not work with the DeleteContainer template
+ */
+void ASFormatter::initContainer(vector<BracketType>* &container, vector<BracketType>* value)
+{
+ if (container != NULL)
+ deleteContainer(container);
+ container = value;
+}
+
+/**
+ * initialize a vector object
+ * T is the type of vector
+ * used for all vectors except bracketTypeStack
+ */
+template<typename T>
+void ASFormatter::initContainer(T &container, T value)
+{
+ // since the ASFormatter object is never deleted,
+ // the existing vectors must be deleted before creating new ones
+ if (container != NULL)
+ deleteContainer(container);
+ container = value;
+}
+
+/**
+ * convert a tab to spaces.
+ * charNum points to the current character to convert to spaces.
+ * tabIncrementIn is the increment that must be added for tab indent characters
+ * to get the correct column for the current tab.
+ * replaces the tab in currentLine with the required number of spaces.
+ * replaces the value of currentChar.
+ */
+void ASFormatter::convertTabToSpaces()
+{
+ assert(currentLine[charNum] == '\t');
+
+ // do NOT replace if in quotes
+ if (isInQuote || isInQuoteContinuation)
+ return;
+
+ size_t indent = getIndentLength();
+ size_t numSpaces = indent - ((tabIncrementIn + charNum) % indent);
+ currentLine.replace(charNum, 1, numSpaces, ' ');
+ currentChar = currentLine[charNum];
+}
+
+/**
+* is it ok to break this block?
+*/
+bool ASFormatter::isOkToBreakBlock(BracketType bracketType) const
+{
+ // Actually, there should not be an ARRAY_TYPE bracket here.
+ // But this will avoid breaking a one line block when there is.
+ // Otherwise they will be formatted differently on consecutive runs.
+ if (isBracketType(bracketType, ARRAY_TYPE)
+ && isBracketType(bracketType, SINGLE_LINE_TYPE))
+ return false;
+ if (!isBracketType(bracketType, SINGLE_LINE_TYPE)
+ || shouldBreakOneLineBlocks
+ || breakCurrentOneLineBlock)
+ return true;
+ return false;
+}
+
+/**
+* check if a sharp header is a paren or nonparen header
+*/
+bool ASFormatter::isSharpStyleWithParen(const string* header) const
+{
+ if (isSharpStyle() && peekNextChar() == '('
+ && (header == &AS_CATCH
+ || header == &AS_DELEGATE))
+ return true;
+ return false;
+}
+
+/**
+ * check for a following header when a comment is reached.
+ * if a header follows, the comments are kept as part of the header block.
+ * firstLine must contain the start of the comment.
+ */
+void ASFormatter::checkForFollowingHeader(const string& firstLine)
+{
+ // look ahead to find the next non-comment text
+ string nextText = peekNextText(firstLine, true);
+ if (nextText.length() == 0 || !isCharPotentialHeader(nextText, 0))
+ return;
+
+ const string* newHeader = ASBeautifier::findHeader(nextText, 0, headers);
+
+ if (newHeader == NULL)
+ return;
+
+ // may need to break if a header follows
+ bool isClosingHeader = (newHeader == &AS_ELSE
+ || newHeader == &AS_CATCH
+ || newHeader == &AS_FINALLY);
+
+ // if a closing header, reset break unless break is requested
+ if (isClosingHeader)
+ {
+ if (!shouldBreakClosingHeaderBlocks)
+ isPrependPostBlockEmptyLineRequested = false;
+ }
+ // if an opening header, break before the comment
+ else
+ {
+ isPrependPostBlockEmptyLineRequested = true;
+ }
+}
+
+/**
+ * process preprocessor statements.
+ * charNum should be the index of the preprocessor directive.
+ *
+ * delete bracketTypeStack entries added by #if if a #else is found.
+ * prevents double entries in the bracketTypeStack.
+ */
+void ASFormatter::processPreprocessor()
+{
+ assert(currentChar == '#');
+
+ const int preproc = charNum + 1;
+
+ if (currentLine.compare(preproc, 2, "if") == 0)
+ {
+ preprocBracketTypeStackSize = bracketTypeStack->size();
+ }
+ else if (currentLine.compare(preproc, 4, "else") == 0)
+ {
+ // delete stack entries added in #if
+ // should be replaced by #else
+ if (preprocBracketTypeStackSize > 0)
+ {
+ int addedPreproc = bracketTypeStack->size() - preprocBracketTypeStackSize;
+ for (int i=0; i < addedPreproc; i++)
+ bracketTypeStack->pop_back();
+ }
+ }
+}
+
+/**
+ * determine if the next line starts a comment
+ * and a header follows the comment or comments
+ */
+bool ASFormatter::commentAndHeaderFollows() const
+{
+ // is the next line a comment
+ string nextLine = sourceIterator->peekNextLine();
+ size_t firstChar = nextLine.find_first_not_of(" \t");
+ if (firstChar == string::npos
+ || !(nextLine.compare(firstChar, 2, "//") == 0
+ || nextLine.compare(firstChar, 2, "/*") == 0))
+ {
+ sourceIterator->peekReset();
+ return false;
+ }
+
+ // if next line is a comment, find the next non-comment text
+ string nextText = peekNextText(nextLine, true);
+ if (nextText.length() == 0 || !isCharPotentialHeader(nextText, 0))
+ return false;
+
+ const string* newHeader = ASBeautifier::findHeader(nextText, 0, headers);
+
+ if (newHeader == NULL)
+ return false;
+
+ bool isClosingHeader = (newHeader == &AS_ELSE
+ || newHeader == &AS_CATCH
+ || newHeader == &AS_FINALLY);
+
+ if (isClosingHeader && !shouldBreakClosingHeaderBlocks)
+ return false;
+
+ return true;
+}
+
+/**
+ * determine if a bracket should be attached or broken
+ * uses brackets in the bracketTypeStack
+ * the last bracket in the bracketTypeStack is the one being formatted
+ * returns true if the bracket should be broken
+ */
+bool ASFormatter::isCurrentBracketBroken() const
+{
+ assert(bracketTypeStack->size() > 0);
+
+ bool breakBracket = false;
+ size_t bracketTypeStackEnd = bracketTypeStack->size()-1;
+
+ if (isBracketType((*bracketTypeStack)[bracketTypeStackEnd], EXTERN_TYPE))
+ {
+ if (currentLineBeginsWithBracket
+ || bracketFormatMode == HORSTMANN_MODE)
+ breakBracket = true;
+ }
+ else if (bracketFormatMode == NONE_MODE)
+ {
+ if (currentLineBeginsWithBracket
+ && (int)currentLineFirstBracketNum == charNum) // lineBeginsWith('{')
+ breakBracket = true;
+ }
+ else if (bracketFormatMode == BREAK_MODE || bracketFormatMode == HORSTMANN_MODE)
+ {
+ breakBracket = true;
+ }
+ else if (bracketFormatMode == LINUX_MODE || bracketFormatMode == STROUSTRUP_MODE)
+ {
+ // break a class if Linux
+ if (isBracketType((*bracketTypeStack)[bracketTypeStackEnd], CLASS_TYPE))
+ {
+ if (bracketFormatMode == LINUX_MODE)
+ breakBracket = true;
+ }
+ // break a namespace or interface if Linux
+ else if (isBracketType((*bracketTypeStack)[bracketTypeStackEnd], NAMESPACE_TYPE)
+ || isBracketType((*bracketTypeStack)[bracketTypeStackEnd], INTERFACE_TYPE))
+ {
+ if (bracketFormatMode == LINUX_MODE)
+ breakBracket = true;
+ }
+ // break the first bracket if a function
+ else if (bracketTypeStackEnd == 1
+ && isBracketType((*bracketTypeStack)[bracketTypeStackEnd], COMMAND_TYPE))
+ {
+ breakBracket = true;
+ }
+ else if (bracketTypeStackEnd > 1)
+ {
+ // break the first bracket after a namespace or extern if a function
+ if (isBracketType((*bracketTypeStack)[bracketTypeStackEnd-1], NAMESPACE_TYPE)
+ || isBracketType((*bracketTypeStack)[bracketTypeStackEnd-1], EXTERN_TYPE))
+ {
+ if (isBracketType((*bracketTypeStack)[bracketTypeStackEnd], COMMAND_TYPE))
+ breakBracket = true;
+ }
+ // if not C style then break the first bracket after a class if a function
+ else if (!isCStyle())
+ {
+ if ((isBracketType((*bracketTypeStack)[bracketTypeStackEnd-1], CLASS_TYPE)
+ || isBracketType((*bracketTypeStack)[bracketTypeStackEnd-1], ARRAY_TYPE)
+ || isBracketType((*bracketTypeStack)[bracketTypeStackEnd-1], STRUCT_TYPE))
+ && isBracketType((*bracketTypeStack)[bracketTypeStackEnd], COMMAND_TYPE))
+ breakBracket = true;
+ }
+ }
+ }
+ return breakBracket;
+}
+
+/**
+ * format comment body
+ * the calling function should have a continue statement after calling this method
+ */
+void ASFormatter::formatCommentBody()
+{
+ assert(isInComment);
+
+ if (isSequenceReached("*/"))
+ {
+ isInComment = false;
+ noTrimCommentContinuation = false;
+ isImmediatelyPostComment = true;
+ appendSequence(AS_CLOSE_COMMENT);
+ goForward(1);
+ if (doesLineStartComment
+ && (currentLine.find_first_not_of(" \t", charNum+1) == string::npos))
+ lineEndsInCommentOnly = true;
+ if (peekNextChar() == '}'
+ && previousCommandChar != ';'
+ && !isBracketType(bracketTypeStack->back(), ARRAY_TYPE)
+ && isOkToBreakBlock(bracketTypeStack->back()))
+ breakLine();
+ }
+ else
+ {
+ appendCurrentChar();
+ // append the comment up to the next tab or comment end
+ // tabs must be checked for convert-tabs before appending
+ while (charNum + 1 < (int) currentLine.length()
+ && currentLine[charNum+1] != '\t'
+ && currentLine.compare(charNum+1, 2, "*/") != 0)
+ {
+ currentChar = currentLine[++charNum];
+ appendCurrentChar();
+ }
+ }
+}
+
+/**
+ * format a comment opener
+ * the comment opener will be appended to the current formattedLine or a new formattedLine as necessary
+ * the calling function should have a continue statement after calling this method
+ */
+void ASFormatter::formatCommentOpener()
+{
+ assert(isSequenceReached("/*"));
+
+ isInComment = true;
+ isImmediatelyPostLineComment = false;
+
+ if (spacePadNum != 0)
+ adjustComments();
+ formattedLineCommentNum = formattedLine.length();
+
+ // must be done BEFORE appendSequence
+ if (previousCommandChar == '{'
+ && !isImmediatelyPostComment
+ && !isImmediatelyPostLineComment)
+ {
+ if (bracketFormatMode == NONE_MODE)
+ {
+ // should a run-in statement be attached?
+ if (currentLineBeginsWithBracket)
+ formatRunIn();
+ }
+ else if (bracketFormatMode == ATTACH_MODE)
+ {
+ // if the bracket was not attached?
+ if (formattedLine[0] == '{'
+ && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE))
+ isInLineBreak = true;
+ }
+ else if (bracketFormatMode == HORSTMANN_MODE)
+ {
+ // should a run-in statement be attached?
+ if (formattedLine[0] == '{')
+ formatRunIn();
+ }
+ }
+ else if (!doesLineStartComment)
+ noTrimCommentContinuation = true;
+
+ // appendSequence will write the previous line
+ appendSequence(AS_OPEN_COMMENT);
+ goForward(1);
+
+ // must be done AFTER appendSequence
+ if (shouldBreakBlocks)
+ {
+ // break before the comment if a header follows the comment
+ // for speed, do not check if previous line is empty,
+ // if previous line is a line comment or if previous line is '{'
+ if (doesLineStartComment
+ && !isImmediatelyPostEmptyLine
+ && !isImmediatelyPostComment
+ && !isImmediatelyPostLineComment
+ && previousCommandChar != '{')
+ {
+ checkForFollowingHeader(currentLine.substr(charNum-1));
+ }
+ }
+
+ if (previousCommandChar == '}')
+ currentHeader = NULL;
+}
+
+/**
+ * format a line comment body
+ * the calling function should have a continue statement after calling this method
+ */
+void ASFormatter::formatLineCommentBody()
+{
+ assert(isInLineComment);
+
+ appendCurrentChar();
+ // append the comment up to the next tab
+ // tabs must be checked for convert-tabs before appending
+ while (charNum + 1 < (int) currentLine.length()
+ && currentLine[charNum+1] != '\t')
+ {
+ currentChar = currentLine[++charNum];
+ appendCurrentChar();
+ }
+
+ // explicitely break a line when a line comment's end is found.
+ if (charNum + 1 == (int) currentLine.length())
+ {
+ isInLineBreak = true;
+ isInLineComment = false;
+ isImmediatelyPostLineComment = true;
+ currentChar = 0; //make sure it is a neutral char.
+ }
+}
+
+/**
+ * format a line comment opener
+ * the line comment opener will be appended to the current formattedLine or a new formattedLine as necessary
+ * the calling function should have a continue statement after calling this method
+ */
+void ASFormatter::formatLineCommentOpener()
+{
+ assert(isSequenceReached("//"));
+
+ if (currentLine[charNum+2] == '\xf2') // check for windows line marker
+ isAppendPostBlockEmptyLineRequested = false;
+
+ isInLineComment = true;
+ isCharImmediatelyPostComment = false;
+
+ // do not indent if in column 1 or 2
+ if (!shouldIndentCol1Comments && !lineCommentNoIndent)
+ {
+ if (charNum == 0)
+ lineCommentNoIndent = true;
+ else if (charNum == 1 && currentLine[0] == ' ')
+ lineCommentNoIndent = true;
+ }
+ // move comment if spaces were added or deleted
+ if (lineCommentNoIndent == false && spacePadNum != 0)
+ adjustComments();
+ formattedLineCommentNum = formattedLine.length();
+
+ // must be done BEFORE appendSequence
+ // check for run-in statement
+ if (previousCommandChar == '{'
+ && !isImmediatelyPostComment
+ && !isImmediatelyPostLineComment)
+ {
+ if (bracketFormatMode == NONE_MODE)
+ {
+ if (currentLineBeginsWithBracket)
+ formatRunIn();
+ }
+ else if (bracketFormatMode == HORSTMANN_MODE)
+ {
+ if (!lineCommentNoIndent)
+ formatRunIn();
+ else
+ isInLineBreak = true;
+ }
+ else if (bracketFormatMode == BREAK_MODE)
+ {
+ if (formattedLine[0] == '{')
+ isInLineBreak = true;
+ }
+ else
+ {
+ if (currentLineBeginsWithBracket)
+ isInLineBreak = true;
+ }
+ }
+
+ // appendSequence will write the previous line
+ appendSequence(AS_OPEN_LINE_COMMENT);
+ goForward(1);
+
+ if (formattedLine.compare(0, 2, "//") == 0)
+ lineIsLineCommentOnly = true;
+
+ // must be done AFTER appendSequence
+ if (shouldBreakBlocks)
+ {
+ // break before the comment if a header follows the line comment
+ // for speed, do not check if previous line is empty,
+ // if previous line is a comment or if previous line is '{'
+ if (lineIsLineCommentOnly
+ && previousCommandChar != '{'
+ && !isImmediatelyPostEmptyLine
+ && !isImmediatelyPostComment
+ && !isImmediatelyPostLineComment)
+ {
+ checkForFollowingHeader(currentLine.substr(charNum-1));
+ }
+ }
+
+ if (previousCommandChar == '}')
+ currentHeader = NULL;
+
+ // if tabbed input don't convert the immediately following tabs to spaces
+ if (getIndentString() == "\t" && lineCommentNoIndent)
+ {
+ while (charNum + 1 < (int) currentLine.length()
+ && currentLine[charNum+1] == '\t')
+ {
+ currentChar = currentLine[++charNum];
+ appendCurrentChar();
+ }
+ }
+
+ // explicitely break a line when a line comment's end is found.
+ if (charNum + 1 == (int) currentLine.length())
+ {
+ isInLineBreak = true;
+ isInLineComment = false;
+ isImmediatelyPostLineComment = true;
+ currentChar = 0; //make sure it is a neutral char.
+ }
+}
+
+/**
+ * format quote body
+ * the calling function should have a continue statement after calling this method
+ */
+void ASFormatter::formatQuoteBody()
+{
+ assert(isInQuote);
+
+ if (isSpecialChar)
+ {
+ isSpecialChar = false;
+ }
+ else if (currentChar == '\\' && !isInVerbatimQuote)
+ {
+ if (peekNextChar() == ' ') // is this '\' at end of line
+ haveLineContinuationChar = true;
+ else
+ isSpecialChar = true;
+ }
+ else if (isInVerbatimQuote && currentChar == '"')
+ {
+ if (peekNextChar() == '"') // check consecutive quotes
+ {
+ appendSequence("\"\"");
+ goForward(1);
+ return;
+ }
+ else
+ {
+ isInQuote = false;
+ isInVerbatimQuote = false;
+ }
+ }
+ else if (quoteChar == currentChar)
+ {
+ isInQuote = false;
+ }
+
+ appendCurrentChar();
+
+ // append the text to the ending quoteChar or an escape sequence
+ // tabs in quotes are NOT changed by convert-tabs
+ if (isInQuote && currentChar != '\\')
+ {
+ while (charNum + 1 < (int) currentLine.length()
+ && currentLine[charNum+1] != quoteChar
+ && currentLine[charNum+1] != '\\')
+ {
+ currentChar = currentLine[++charNum];
+ appendCurrentChar();
+ }
+ }
+}
+
+/**
+ * format a quote opener
+ * the quote opener will be appended to the current formattedLine or a new formattedLine as necessary
+ * the calling function should have a continue statement after calling this method
+ */
+void ASFormatter::formatQuoteOpener()
+{
+ assert(currentChar == '"' || currentChar == '\'');
+
+ isInQuote = true;
+ quoteChar = currentChar;
+ if (isSharpStyle() && previousChar == '@')
+ isInVerbatimQuote = true;
+
+ // a quote following a bracket is an array
+ if (previousCommandChar == '{'
+ && !isImmediatelyPostComment
+ && !isImmediatelyPostLineComment
+ && isNonInStatementArray
+ && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)
+ && !isWhiteSpace(peekNextChar()))
+ {
+ if (bracketFormatMode == NONE_MODE)
+ {
+ if (currentLineBeginsWithBracket)
+ formatRunIn();
+ }
+ else if (bracketFormatMode == HORSTMANN_MODE)
+ {
+ if (!lineCommentNoIndent)
+ formatRunIn();
+ else
+ isInLineBreak = true;
+ }
+ else if (bracketFormatMode == BREAK_MODE)
+ {
+ if (formattedLine[0] == '{')
+ isInLineBreak = true;
+ }
+ else
+ {
+ if (currentLineBeginsWithBracket)
+ isInLineBreak = true;
+ }
+ }
+ previousCommandChar = ' ';
+ appendCurrentChar();
+}
+
+/**
+ * get the next line comment adjustment that results from breaking a closing bracket.
+ * the bracket must be on the same line as the closing header.
+ * i.e "} else" changed to "} \n else".
+ */
+int ASFormatter::getNextLineCommentAdjustment()
+{
+ assert(foundClosingHeader && previousNonWSChar == '}');
+ if (charNum < 1)
+ return 0;
+ size_t lastBracket = currentLine.rfind('}', charNum - 1);
+ if (lastBracket != string::npos)
+ return (lastBracket - charNum); // return a negative number
+ return 0;
+}
+
+LineEndFormat ASFormatter::getLineEndFormat() const
+{
+ return lineEnd;
+}
+
+/**
+ * get the current line comment adjustment that results from attaching
+ * a closing header to a closing bracket.
+ * the bracket must be on the line previous to the closing header.
+ * the adjustment is 2 chars, one for the bracket and one for the space.
+ * i.e "} \n else" changed to "} else".
+ */
+int ASFormatter::getCurrentLineCommentAdjustment()
+{
+ assert(foundClosingHeader && previousNonWSChar == '}');
+ if (charNum < 1)
+ return 2;
+ size_t lastBracket = currentLine.rfind('}', charNum - 1);
+ if (lastBracket == string::npos)
+ return 2;
+ return 0;
+}
+
+/**
+ * get the previous word
+ * the argument 'end' must point to the search start.
+ *
+ * @return is the previous word.
+ */
+string ASFormatter::getPreviousWord(const string& line, int currPos) const
+{
+ // get the last legal word (may be a number)
+ if (currPos == 0)
+ return string();
+
+ size_t end = line.find_last_not_of(" \t", currPos-1);
+ if (end == string::npos || !isLegalNameChar(line[end]))
+ return string();
+
+ int start; // start of the previous word
+ for (start = end; start > -1; start--)
+ {
+ if (!isLegalNameChar(line[start]) || line[start] == '.')
+ break;
+ }
+ start++;
+
+ return (line.substr(start, end-start+1));
+}
+
+/**
+ * check if a line break is needed when a closing bracket
+ * is followed by a closing header.
+ * the break depends on the bracketFormatMode and other factors.
+ */
+void ASFormatter::isLineBreakBeforeClosingHeader()
+{
+ assert(foundClosingHeader && previousNonWSChar == '}');
+ if (bracketFormatMode == BREAK_MODE || bracketFormatMode == HORSTMANN_MODE)
+ {
+ isInLineBreak = true;
+ }
+ else if (bracketFormatMode == NONE_MODE)
+ {
+ if (shouldBreakClosingHeaderBrackets
+ || getBracketIndent() || getBlockIndent())
+ {
+ isInLineBreak = true;
+ }
+ else
+ {
+ appendSpacePad();
+ // is closing bracket broken?
+ size_t i = currentLine.find_first_not_of(" \t");
+ if (i != string::npos && currentLine[i] == '}')
+ isInLineBreak = false;
+
+ if (shouldBreakBlocks)
+ isAppendPostBlockEmptyLineRequested = false;
+ }
+ }
+ // bracketFormatMode == ATTACH_MODE, LINUX_MODE, STROUSTRUP_MODE
+ else
+ {
+ if (shouldBreakClosingHeaderBrackets
+ || getBracketIndent() || getBlockIndent())
+ {
+ isInLineBreak = true;
+ }
+ else
+ {
+ // if a blank line does not preceed this
+ // or last line is not a one line block, attach header
+ bool previousLineIsEmpty = isEmptyLine(formattedLine);
+ bool previousLineIsOneLineBlock = false;
+ size_t firstBracket = findNextChar(formattedLine, '{');
+ if (firstBracket != string::npos)
+ previousLineIsOneLineBlock = isOneLineBlockReached(formattedLine, firstBracket);
+ if (!previousLineIsEmpty
+ && !previousLineIsOneLineBlock)
+ {
+ isInLineBreak = false;
+ appendSpacePad();
+ spacePadNum = 0; // don't count as comment padding
+ }
+
+ if (shouldBreakBlocks)
+ isAppendPostBlockEmptyLineRequested = false;
+ }
+ }
+}
+
+/**
+ * Add brackets to a single line statement following a header.
+ * Brackets are not added if the proper conditions are not met.
+ * Brackets are added to the currentLine.
+ */
+bool ASFormatter::addBracketsToStatement()
+{
+ assert(isImmediatelyPostHeader);
+
+ if (currentHeader != &AS_IF
+ && currentHeader != &AS_ELSE
+ && currentHeader != &AS_FOR
+ && currentHeader != &AS_WHILE
+ && currentHeader != &AS_DO
+ && currentHeader != &AS_FOREACH)
+ return false;
+
+ // do not add if a header follows (i.e. else if)
+ if (isCharPotentialHeader(currentLine, charNum))
+ if (findHeader(headers) != NULL)
+ return false;
+
+ // find the next semi-colon
+ size_t nextSemiColon = findNextChar(currentLine, ';', charNum+1);
+ if (nextSemiColon == string::npos)
+ return false;
+
+ // add closing bracket before changing the line length
+ if (nextSemiColon == currentLine.length() - 1)
+ currentLine.append(" }");
+ else
+ currentLine.insert(nextSemiColon + 1, " }");
+ // add opening bracket
+ currentLine.insert(charNum, "{ ");
+ currentChar = '{';
+ // remove extra spaces
+ if (!shouldAddOneLineBrackets)
+ {
+ size_t lastText = formattedLine.find_last_not_of(" \t");
+ if ((formattedLine.length() - 1) - lastText > 1)
+ formattedLine.erase(lastText + 1);
+ }
+ return true;
+}
+
+/**
+ * Find the next character that is not in quotes or a comment.
+ *
+ * @param line the line to be searched.
+ * @param searchChar the char to find.
+ * @param searchStart the char to find.
+ * @return the position on the line or string::npos if not found.
+ */
+size_t ASFormatter::findNextChar(string& line, char searchChar, int searchStart /*0*/)
+{
+ // find the next searchChar
+ size_t i;
+ for (i = searchStart; i < line.length(); i++)
+ {
+ if (line.compare(i, 2, "//") == 0)
+ return string::npos;
+ if (line.compare(i, 2, "/*") == 0)
+ {
+ size_t endComment = line.find("*/", i+2);
+ if (endComment == string::npos)
+ return string::npos;
+ i = endComment + 2;
+ }
+ if (line[i] == '\'' || line[i] == '\"')
+ {
+ char quote = line[i];
+ while (i < line.length())
+ {
+ size_t endQuote = line.find(quote, i+1);
+ if (endQuote == string::npos)
+ return string::npos;
+ i = endQuote;
+ if (line[endQuote-1] != '\\') // check for '\"'
+ break;
+ if (line[endQuote-2] == '\\') // check for '\\'
+ break;
+ }
+ }
+
+ if (line[i] == searchChar)
+ break;
+
+ // for now don't process C# 'delegate' brackets
+ // do this last in case the search char is a '{'
+ if (line[i] == '{')
+ return string::npos;
+ }
+ if (i >= line.length()) // didn't find searchChar
+ return string::npos;
+
+ return i;
+}
+
+/**
+ * Look ahead in the file to see if a struct has access modifiers.
+ *
+ * @param line a reference to the line to indent.
+ * @param index the current line index.
+ * @return true if the struct has access modifiers.
+ */
+bool ASFormatter::isStructAccessModified(string &firstLine, size_t index) const
+{
+ assert(firstLine[index] == '{');
+ assert(isCStyle());
+
+ bool isFirstLine = true;
+ bool needReset = false;
+ size_t bracketCount = 1;
+ string nextLine = firstLine.substr(index + 1);
+
+ // find the first non-blank text, bypassing all comments.
+ bool isInComment = false;
+ while (sourceIterator->hasMoreLines())
+ {
+ if (isFirstLine)
+ isFirstLine = false;
+ else
+ {
+ nextLine = sourceIterator->peekNextLine();
+ needReset = true;
+ }
+ // parse the line
+ for (size_t i = 0; i < nextLine.length(); i++)
+ {
+ if (isWhiteSpace(nextLine[i]))
+ continue;
+ if (nextLine.compare(i, 2, "/*") == 0)
+ isInComment = true;
+ if (isInComment)
+ {
+ i = nextLine.find("*/", i);
+ if (i == string::npos)
+ {
+ i = nextLine.length();
+ continue;
+ }
+ i++;
+ isInComment = false;
+ continue;
+ }
+ if (nextLine.compare(i, 2, "//") == 0)
+ {
+ i = nextLine.length();
+ continue;
+ }
+ // handle brackets
+ if (nextLine[i] == '{')
+ bracketCount++;
+ if (nextLine[i] == '}')
+ bracketCount--;
+ if (bracketCount == 0)
+ {
+ if (needReset)
+ sourceIterator->peekReset();
+ return false;
+ }
+ // check for access modifiers
+ if (isCharPotentialHeader(nextLine, i))
+ {
+ if (findKeyword(nextLine, i, AS_PUBLIC)
+ || findKeyword(nextLine, i, AS_PRIVATE)
+ || findKeyword(nextLine, i, AS_PROTECTED))
+ {
+ if (needReset)
+ sourceIterator->peekReset();
+ return true;
+ }
+ string name = getCurrentWord(nextLine, i);
+ i += name.length() - 1;
+ }
+ } // end of for loop
+ } // end of while loop
+
+ if (needReset)
+ sourceIterator->peekReset();
+ return false;
+}
+
+/**
+ * Check to see if this is an EXEC SQL statement.
+ *
+ * @param line a reference to the line to indent.
+ * @param index the current line index.
+ * @return true if the statement is EXEC SQL.
+ */
+bool ASFormatter::isExecSQL(string &line, size_t index) const
+{
+ if (line[index] != 'e' && line[index] != 'E') // quick check to reject most
+ return false;
+ string word;
+ if (isCharPotentialHeader(line, index))
+ word = getCurrentWord(line, index);
+ for (size_t i = 0; i < word.length(); i++)
+ word[i] = (char) toupper(word[i]);
+ if (word != "EXEC")
+ return false;
+ size_t index2 = index + word.length();
+ index2 = line.find_first_not_of(" \t", index2);
+ if (index2 == string::npos)
+ return false;
+ word.erase();
+ if (isCharPotentialHeader(line, index2))
+ word = getCurrentWord(line, index2);
+ for (size_t i = 0; i < word.length(); i++)
+ word[i] = (char) toupper(word[i]);
+ if (word != "SQL")
+ return false;
+ return true;
+}
+
+/**
+ * The continuation lines must be adjusted so the leading spaces
+ * is equivalent to the text on the opening line.
+ *
+ * Updates currentLine and charNum.
+ */
+void ASFormatter::trimContinuationLine()
+{
+ size_t len = currentLine.length();
+ size_t indent = getIndentLength();
+ charNum = 0;
+
+ if (leadingSpaces > 0 && len > 0)
+ {
+ size_t i;
+ size_t continuationIncrementIn = 0;
+ for (i = 0; (i < len) && (i + continuationIncrementIn < leadingSpaces); i++)
+ {
+ if (!isWhiteSpace(currentLine[i])) // don't delete any text
+ {
+ i = 0;
+ continuationIncrementIn = tabIncrementIn;
+ break;
+ }
+ if (currentLine[i] == '\t')
+ continuationIncrementIn += indent - 1 - ((continuationIncrementIn + i) % indent);
+ }
+
+ if ((int) continuationIncrementIn == tabIncrementIn)
+ charNum = i;
+ else
+ {
+ // build a new line with the equivalent leading chars
+ string newLine;
+ int leadingChars = 0;
+ if ((int) leadingSpaces > tabIncrementIn)
+ leadingChars = leadingSpaces - tabIncrementIn;
+ newLine.append(leadingChars, ' ');
+ newLine.append(currentLine, i, len-i);
+ currentLine = newLine;
+ charNum = leadingChars;
+ }
+ if (i >= len)
+ charNum = 0;
+ }
+ return;
+}
+
+
+} // end namespace astyle
diff --git a/support/highlight/src/core/astyle/ASResource.cpp b/support/highlight/src/core/astyle/ASResource.cpp
new file mode 100644
index 0000000000..c2781c88a3
--- /dev/null
+++ b/support/highlight/src/core/astyle/ASResource.cpp
@@ -0,0 +1,547 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Copyright (C) 2006-2010 by Jim Pattee <jimp03@email.com>
+ * Copyright (C) 1998-2002 by Tal Davidson
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>
+ *
+ * This file is a part of Artistic Style - an indentation and
+ * reformatting tool for C, C++, C# and Java source files.
+ * <http://astyle.sourceforge.net>
+ *
+ * Artistic Style is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Artistic Style is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Artistic Style. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+#include "astyle.h"
+#include <algorithm>
+
+
+namespace astyle
+{
+const string ASResource::AS_IF = string("if");
+const string ASResource::AS_ELSE = string("else");
+const string ASResource::AS_FOR = string("for");
+const string ASResource::AS_DO = string("do");
+const string ASResource::AS_WHILE = string("while");
+const string ASResource::AS_SWITCH = string("switch");
+const string ASResource::AS_CASE = string("case");
+const string ASResource::AS_DEFAULT = string("default");
+const string ASResource::AS_CLASS = string("class");
+const string ASResource::AS_STRUCT = string("struct");
+const string ASResource::AS_UNION = string("union");
+const string ASResource::AS_INTERFACE = string("interface");
+const string ASResource::AS_NAMESPACE = string("namespace");
+const string ASResource::AS_EXTERN = string("extern");
+const string ASResource::AS_ENUM = string("enum");
+const string ASResource::AS_PUBLIC = string("public");
+const string ASResource::AS_PROTECTED = string("protected");
+const string ASResource::AS_PRIVATE = string("private");
+const string ASResource::AS_STATIC = string("static");
+const string ASResource::AS_SYNCHRONIZED = string("synchronized");
+const string ASResource::AS_OPERATOR = string("operator");
+const string ASResource::AS_TEMPLATE = string("template");
+const string ASResource::AS_TRY = string("try");
+const string ASResource::AS_CATCH = string("catch");
+const string ASResource::AS_FINALLY = string("finally");
+const string ASResource::AS_THROWS = string("throws");
+const string ASResource::AS_CONST = string("const");
+const string ASResource::AS_WHERE = string("where");
+const string ASResource::AS_NEW = string("new");
+
+const string ASResource::AS_ASM = string("asm");
+const string ASResource::AS__ASM__ = string("__asm__");
+const string ASResource::AS_MS_ASM = string("_asm");
+const string ASResource::AS_MS__ASM = string("__asm");
+
+const string ASResource::AS_BAR_DEFINE = string("#define");
+const string ASResource::AS_BAR_INCLUDE = string("#include");
+const string ASResource::AS_BAR_IF = string("#if");
+const string ASResource::AS_BAR_EL = string("#el");
+const string ASResource::AS_BAR_ENDIF = string("#endif");
+
+const string ASResource::AS_OPEN_BRACKET = string("{");
+const string ASResource::AS_CLOSE_BRACKET = string("}");
+const string ASResource::AS_OPEN_LINE_COMMENT = string("//");
+const string ASResource::AS_OPEN_COMMENT = string("/*");
+const string ASResource::AS_CLOSE_COMMENT = string("*/");
+
+const string ASResource::AS_ASSIGN = string("=");
+const string ASResource::AS_PLUS_ASSIGN = string("+=");
+const string ASResource::AS_MINUS_ASSIGN = string("-=");
+const string ASResource::AS_MULT_ASSIGN = string("*=");
+const string ASResource::AS_DIV_ASSIGN = string("/=");
+const string ASResource::AS_MOD_ASSIGN = string("%=");
+const string ASResource::AS_OR_ASSIGN = string("|=");
+const string ASResource::AS_AND_ASSIGN = string("&=");
+const string ASResource::AS_XOR_ASSIGN = string("^=");
+const string ASResource::AS_GR_GR_ASSIGN = string(">>=");
+const string ASResource::AS_LS_LS_ASSIGN = string("<<=");
+const string ASResource::AS_GR_GR_GR_ASSIGN = string(">>>=");
+const string ASResource::AS_LS_LS_LS_ASSIGN = string("<<<=");
+const string ASResource::AS_GCC_MIN_ASSIGN = string("<?");
+const string ASResource::AS_GCC_MAX_ASSIGN = string(">?");
+
+const string ASResource::AS_RETURN = string("return");
+const string ASResource::AS_CIN = string("cin");
+const string ASResource::AS_COUT = string("cout");
+const string ASResource::AS_CERR = string("cerr");
+
+const string ASResource::AS_EQUAL = string("==");
+const string ASResource::AS_PLUS_PLUS = string("++");
+const string ASResource::AS_MINUS_MINUS = string("--");
+const string ASResource::AS_NOT_EQUAL = string("!=");
+const string ASResource::AS_GR_EQUAL = string(">=");
+const string ASResource::AS_GR_GR = string(">>");
+const string ASResource::AS_GR_GR_GR = string(">>>");
+const string ASResource::AS_LS_EQUAL = string("<=");
+const string ASResource::AS_LS_LS = string("<<");
+const string ASResource::AS_LS_LS_LS = string("<<<");
+const string ASResource::AS_QUESTION_QUESTION = string("??");
+const string ASResource::AS_EQUAL_GR = string("=>"); // C# lambda expression arrow
+const string ASResource::AS_ARROW = string("->");
+const string ASResource::AS_AND = string("&&");
+const string ASResource::AS_OR = string("||");
+const string ASResource::AS_COLON_COLON = string("::");
+const string ASResource::AS_PAREN_PAREN = string("()");
+const string ASResource::AS_BLPAREN_BLPAREN = string("[]");
+
+const string ASResource::AS_PLUS = string("+");
+const string ASResource::AS_MINUS = string("-");
+const string ASResource::AS_MULT = string("*");
+const string ASResource::AS_DIV = string("/");
+const string ASResource::AS_MOD = string("%");
+const string ASResource::AS_GR = string(">");
+const string ASResource::AS_LS = string("<");
+const string ASResource::AS_NOT = string("!");
+const string ASResource::AS_BIT_OR = string("|");
+const string ASResource::AS_BIT_AND = string("&");
+const string ASResource::AS_BIT_NOT = string("~");
+const string ASResource::AS_BIT_XOR = string("^");
+const string ASResource::AS_QUESTION = string("?");
+const string ASResource::AS_COLON = string(":");
+const string ASResource::AS_COMMA = string(",");
+const string ASResource::AS_SEMICOLON = string(";");
+
+const string ASResource::AS_FOREACH = string("foreach");
+const string ASResource::AS_LOCK = string("lock");
+const string ASResource::AS_UNSAFE = string("unsafe");
+const string ASResource::AS_FIXED = string("fixed");
+const string ASResource::AS_GET = string("get");
+const string ASResource::AS_SET = string("set");
+const string ASResource::AS_ADD = string("add");
+const string ASResource::AS_REMOVE = string("remove");
+const string ASResource::AS_DELEGATE = string("delegate");
+const string ASResource::AS_UNCHECKED = string("unchecked");
+
+const string ASResource::AS_CONST_CAST = string("const_cast");
+const string ASResource::AS_DYNAMIC_CAST = string("dynamic_cast");
+const string ASResource::AS_REINTERPRET_CAST = string("reinterpret_cast");
+const string ASResource::AS_STATIC_CAST = string("static_cast");
+
+
+/**
+ * Sort comparison function.
+ * Compares the length of the value of pointers in the vectors.
+ * The LONGEST strings will be first in the vector.
+ *
+ * @params the string pointers to be compared.
+ */
+bool sortOnLength(const string *a, const string *b)
+{
+ return (*a).length() > (*b).length();
+}
+
+/**
+ * Sort comparison function.
+ * Compares the value of pointers in the vectors.
+ *
+ * @params the string pointers to be compared.
+ */
+bool sortOnName(const string *a, const string *b)
+{
+ return *a < *b;
+}
+
+/**
+ * Build the vector of assignment operators.
+ * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp
+ *
+ * @param assignmentOperators a reference to the vector to be built.
+ */
+void ASResource::buildAssignmentOperators(vector<const string*>* assignmentOperators)
+{
+ assignmentOperators->push_back(&AS_ASSIGN);
+ assignmentOperators->push_back(&AS_PLUS_ASSIGN);
+ assignmentOperators->push_back(&AS_MINUS_ASSIGN);
+ assignmentOperators->push_back(&AS_MULT_ASSIGN);
+ assignmentOperators->push_back(&AS_DIV_ASSIGN);
+ assignmentOperators->push_back(&AS_MOD_ASSIGN);
+ assignmentOperators->push_back(&AS_OR_ASSIGN);
+ assignmentOperators->push_back(&AS_AND_ASSIGN);
+ assignmentOperators->push_back(&AS_XOR_ASSIGN);
+
+ // Java
+ assignmentOperators->push_back(&AS_GR_GR_GR_ASSIGN);
+ assignmentOperators->push_back(&AS_GR_GR_ASSIGN);
+ assignmentOperators->push_back(&AS_LS_LS_ASSIGN);
+
+ // Unknown
+ assignmentOperators->push_back(&AS_LS_LS_LS_ASSIGN);
+
+ sort(assignmentOperators->begin(), assignmentOperators->end(), sortOnLength);
+}
+
+/**
+ * Build the vector of C++ cast operators.
+ * Used by ONLY ASFormatter.cpp
+ *
+ * @param castOperators a reference to the vector to be built.
+ */
+void ASResource::buildCastOperators(vector<const string*>* castOperators)
+{
+ castOperators->push_back(&AS_CONST_CAST);
+ castOperators->push_back(&AS_DYNAMIC_CAST);
+ castOperators->push_back(&AS_REINTERPRET_CAST);
+ castOperators->push_back(&AS_STATIC_CAST);
+}
+
+/**
+ * Build the vector of header words.
+ * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp
+ *
+ * @param headers a reference to the vector to be built.
+ */
+void ASResource::buildHeaders(vector<const string*>* headers, int fileType, bool beautifier)
+{
+ headers->push_back(&AS_IF);
+ headers->push_back(&AS_ELSE);
+ headers->push_back(&AS_FOR);
+ headers->push_back(&AS_WHILE);
+ headers->push_back(&AS_DO);
+ headers->push_back(&AS_SWITCH);
+ headers->push_back(&AS_TRY);
+ headers->push_back(&AS_CATCH);
+
+ if (fileType == JAVA_TYPE)
+ {
+ headers->push_back(&AS_FINALLY);
+ headers->push_back(&AS_SYNCHRONIZED);
+ }
+
+ if (fileType == SHARP_TYPE)
+ {
+ headers->push_back(&AS_FINALLY);
+ headers->push_back(&AS_FOREACH);
+ headers->push_back(&AS_LOCK);
+// headers->push_back(&AS_UNSAFE);
+ headers->push_back(&AS_FIXED);
+ headers->push_back(&AS_GET);
+ headers->push_back(&AS_SET);
+ headers->push_back(&AS_ADD);
+ headers->push_back(&AS_REMOVE);
+ }
+
+ if (beautifier)
+ {
+ headers->push_back(&AS_CASE);
+ headers->push_back(&AS_DEFAULT);
+
+ if (fileType == C_TYPE)
+ {
+ headers->push_back(&AS_CONST);
+ headers->push_back(&AS_TEMPLATE);
+ }
+
+ if (fileType == JAVA_TYPE)
+ {
+ headers->push_back(&AS_STATIC); // for static constructor
+ }
+ }
+ sort(headers->begin(), headers->end(), sortOnName);
+}
+
+/**
+ * Build the vector of indentable headers.
+ * Used by ONLY ASBeautifier.cpp
+ *
+ * @param indentableHeaders a reference to the vector to be built.
+ */
+void ASResource::buildIndentableHeaders(vector<const string*>* indentableHeaders)
+{
+ indentableHeaders->push_back(&AS_RETURN);
+// indentableHeaders->push_back(&AS_COUT);
+// indentableHeaders->push_back(&AS_CERR);
+// indentableHeaders->push_back(&AS_CIN);
+
+ sort(indentableHeaders->begin(), indentableHeaders->end(), sortOnName);
+}
+
+/**
+ * Build the vector of non-assignment operators.
+ * Used by ONLY ASBeautifier.cpp
+ *
+ * @param nonAssignmentOperators a reference to the vector to be built.
+ */
+void ASResource::buildNonAssignmentOperators(vector<const string*>* nonAssignmentOperators)
+{
+ nonAssignmentOperators->push_back(&AS_EQUAL);
+ nonAssignmentOperators->push_back(&AS_PLUS_PLUS);
+ nonAssignmentOperators->push_back(&AS_MINUS_MINUS);
+ nonAssignmentOperators->push_back(&AS_NOT_EQUAL);
+ nonAssignmentOperators->push_back(&AS_GR_EQUAL);
+ nonAssignmentOperators->push_back(&AS_GR_GR_GR);
+ nonAssignmentOperators->push_back(&AS_GR_GR);
+ nonAssignmentOperators->push_back(&AS_LS_EQUAL);
+ nonAssignmentOperators->push_back(&AS_LS_LS_LS);
+ nonAssignmentOperators->push_back(&AS_LS_LS);
+ nonAssignmentOperators->push_back(&AS_ARROW);
+ nonAssignmentOperators->push_back(&AS_AND);
+ nonAssignmentOperators->push_back(&AS_OR);
+
+ sort(nonAssignmentOperators->begin(), nonAssignmentOperators->end(), sortOnLength);
+}
+
+/**
+ * Build the vector of header non-paren headers.
+ * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp
+ *
+ * @param nonParenHeaders a reference to the vector to be built.
+ */
+void ASResource::buildNonParenHeaders(vector<const string*>* nonParenHeaders, int fileType, bool beautifier)
+{
+ nonParenHeaders->push_back(&AS_ELSE);
+ nonParenHeaders->push_back(&AS_DO);
+ nonParenHeaders->push_back(&AS_TRY);
+
+ if (fileType == JAVA_TYPE)
+ {
+ nonParenHeaders->push_back(&AS_FINALLY);
+ }
+
+ if (fileType == SHARP_TYPE)
+ {
+ nonParenHeaders->push_back(&AS_CATCH); // can be a paren or non-paren header
+ nonParenHeaders->push_back(&AS_FINALLY);
+// nonParenHeaders->push_back(&AS_UNSAFE);
+ nonParenHeaders->push_back(&AS_GET);
+ nonParenHeaders->push_back(&AS_SET);
+ nonParenHeaders->push_back(&AS_ADD);
+ nonParenHeaders->push_back(&AS_REMOVE);
+ }
+
+ if (beautifier)
+ {
+ nonParenHeaders->push_back(&AS_CASE);
+ nonParenHeaders->push_back(&AS_DEFAULT);
+ if (fileType == C_TYPE)
+ {
+ nonParenHeaders->push_back(&AS_CONST);
+ nonParenHeaders->push_back(&AS_TEMPLATE);
+ }
+ if (fileType == JAVA_TYPE)
+ {
+ nonParenHeaders->push_back(&AS_STATIC);
+ }
+ }
+ sort(nonParenHeaders->begin(), nonParenHeaders->end(), sortOnName);
+}
+
+/**
+ * Build the vector of operators.
+ * Used by ONLY ASFormatter.cpp
+ *
+ * @param operators a reference to the vector to be built.
+ */
+void ASResource::buildOperators(vector<const string*>* operators)
+{
+ operators->push_back(&AS_PLUS_ASSIGN);
+ operators->push_back(&AS_MINUS_ASSIGN);
+ operators->push_back(&AS_MULT_ASSIGN);
+ operators->push_back(&AS_DIV_ASSIGN);
+ operators->push_back(&AS_MOD_ASSIGN);
+ operators->push_back(&AS_OR_ASSIGN);
+ operators->push_back(&AS_AND_ASSIGN);
+ operators->push_back(&AS_XOR_ASSIGN);
+ operators->push_back(&AS_EQUAL);
+ operators->push_back(&AS_PLUS_PLUS);
+ operators->push_back(&AS_MINUS_MINUS);
+ operators->push_back(&AS_NOT_EQUAL);
+ operators->push_back(&AS_GR_EQUAL);
+ operators->push_back(&AS_GR_GR_GR_ASSIGN);
+ operators->push_back(&AS_GR_GR_ASSIGN);
+ operators->push_back(&AS_GR_GR_GR);
+ operators->push_back(&AS_GR_GR);
+ operators->push_back(&AS_LS_EQUAL);
+ operators->push_back(&AS_LS_LS_LS_ASSIGN);
+ operators->push_back(&AS_LS_LS_ASSIGN);
+ operators->push_back(&AS_LS_LS_LS);
+ operators->push_back(&AS_LS_LS);
+ operators->push_back(&AS_QUESTION_QUESTION);
+ operators->push_back(&AS_EQUAL_GR);
+ operators->push_back(&AS_GCC_MIN_ASSIGN);
+ operators->push_back(&AS_GCC_MAX_ASSIGN);
+ operators->push_back(&AS_ARROW);
+ operators->push_back(&AS_AND);
+ operators->push_back(&AS_OR);
+ operators->push_back(&AS_COLON_COLON);
+ operators->push_back(&AS_PLUS);
+ operators->push_back(&AS_MINUS);
+ operators->push_back(&AS_MULT);
+ operators->push_back(&AS_DIV);
+ operators->push_back(&AS_MOD);
+ operators->push_back(&AS_QUESTION);
+ operators->push_back(&AS_COLON);
+ operators->push_back(&AS_ASSIGN);
+ operators->push_back(&AS_LS);
+ operators->push_back(&AS_GR);
+ operators->push_back(&AS_NOT);
+ operators->push_back(&AS_BIT_OR);
+ operators->push_back(&AS_BIT_AND);
+ operators->push_back(&AS_BIT_NOT);
+ operators->push_back(&AS_BIT_XOR);
+
+ sort(operators->begin(), operators->end(), sortOnLength);
+}
+
+/**
+ * Build the vector of pre-block statements.
+ * Used by ONLY ASBeautifier.cpp
+ * NOTE: Cannot be both a header and a preBlockStatement.
+ *
+ * @param preBlockStatements a reference to the vector to be built.
+ */
+void ASResource::buildPreBlockStatements(vector<const string*>* preBlockStatements, int fileType)
+{
+ preBlockStatements->push_back(&AS_CLASS);
+ if (fileType == C_TYPE)
+ {
+ preBlockStatements->push_back(&AS_STRUCT);
+ preBlockStatements->push_back(&AS_UNION);
+ preBlockStatements->push_back(&AS_NAMESPACE);
+ }
+ if (fileType == JAVA_TYPE)
+ {
+ preBlockStatements->push_back(&AS_INTERFACE);
+ preBlockStatements->push_back(&AS_THROWS);
+ }
+ if (fileType == SHARP_TYPE)
+ {
+ preBlockStatements->push_back(&AS_INTERFACE);
+ preBlockStatements->push_back(&AS_NAMESPACE);
+ preBlockStatements->push_back(&AS_WHERE);
+ preBlockStatements->push_back(&AS_STRUCT);
+ }
+ sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName);
+}
+
+/**
+ * Build the vector of pre-command headers.
+ * Used by ONLY ASFormatter.cpp
+ *
+ * @param preCommandHeaders a reference to the vector to be built.
+ */
+void ASResource::buildPreCommandHeaders(vector<const string*>* preCommandHeaders, int fileType)
+{
+ if (fileType == C_TYPE)
+ {
+ preCommandHeaders->push_back(&AS_CONST);
+ }
+
+ if (fileType == JAVA_TYPE)
+ {
+ preCommandHeaders->push_back(&AS_THROWS);
+ }
+
+ if (fileType == SHARP_TYPE)
+ {
+ preCommandHeaders->push_back(&AS_WHERE);
+ }
+
+ sort(preCommandHeaders->begin(), preCommandHeaders->end(), sortOnName);
+}
+
+/**
+ * Build the vector of pre-definition headers.
+ * Used by ONLY ASFormatter.cpp
+ * NOTE: Do NOT add 'enum' here. It is an array type bracket.
+ * NOTE: Do NOT add 'extern' here. Do not want an extra indent.
+ *
+ * @param preDefinitionHeaders a reference to the vector to be built.
+ */
+void ASResource::buildPreDefinitionHeaders(vector<const string*>* preDefinitionHeaders, int fileType)
+{
+ preDefinitionHeaders->push_back(&AS_CLASS);
+ if (fileType == C_TYPE)
+ {
+ preDefinitionHeaders->push_back(&AS_STRUCT);
+ preDefinitionHeaders->push_back(&AS_UNION);
+ preDefinitionHeaders->push_back(&AS_NAMESPACE);
+ }
+ if (fileType == JAVA_TYPE)
+ {
+ preDefinitionHeaders->push_back(&AS_INTERFACE);
+ }
+ if (fileType == SHARP_TYPE)
+ {
+ preDefinitionHeaders->push_back(&AS_STRUCT);
+ preDefinitionHeaders->push_back(&AS_INTERFACE);
+ preDefinitionHeaders->push_back(&AS_NAMESPACE);
+ }
+ sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * ASBase Funtions
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// check if a specific line position contains a keyword.
+bool ASBase::findKeyword(const string &line, int i, const string &keyword) const
+{
+ assert(isCharPotentialHeader(line, i));
+ // check the word
+ const size_t keywordLength = keyword.length();
+ const size_t wordEnd = i + keywordLength;
+ if (wordEnd > line.length())
+ return false;
+ if (line.compare(i, keywordLength, keyword) != 0)
+ return false;
+ // check that this is not part of a longer word
+ if (wordEnd == line.length())
+ return true;
+ if (isLegalNameChar(line[wordEnd]))
+ return false;
+ // is not a keyword if part of a definition
+ const char peekChar = peekNextChar(line, wordEnd - 1);
+ if (peekChar == ',' || peekChar == ')')
+ return false;
+ return true;
+}
+
+// get the current word on a line
+// index must point to the beginning of the word
+string ASBase::getCurrentWord(const string& line, size_t index) const
+{
+ assert(isCharPotentialHeader(line, index));
+ size_t lineLength = line.length();
+ size_t i;
+ for (i = index; i < lineLength; i++)
+ {
+ if (!isLegalNameChar(line[i]))
+ break;
+ }
+ return line.substr(index, i - index);
+}
+
+} // end namespace astyle
diff --git a/support/highlight/src/core/astyle/ASStreamIterator.cpp b/support/highlight/src/core/astyle/ASStreamIterator.cpp
new file mode 100644
index 0000000000..fe1cbee37c
--- /dev/null
+++ b/support/highlight/src/core/astyle/ASStreamIterator.cpp
@@ -0,0 +1,167 @@
+
+#include "ASStreamIterator.h"
+
+namespace astyle
+{
+
+
+ASStreamIterator::ASStreamIterator(istream *in)
+{
+ inStream = in;
+ buffer.reserve(200);
+ eolWindows = eolLinux = eolMacOld = 0;
+ peekStart = 0;
+ prevLineDeleted = false;
+ checkForEmptyLine = false;
+}
+
+
+ASStreamIterator::~ASStreamIterator()
+{
+}
+
+// save the last input line after input has reached EOF
+
+void ASStreamIterator::saveLastInputLine()
+{
+ assert(inStream->eof());
+ prevBuffer = buffer;
+}
+
+/**
+ * read the input stream, delete any end of line characters,
+ * and build a string that contains the input line.
+ *
+ * @return string containing the next input line minus any end of line characters
+ */
+//template<typename T>
+string ASStreamIterator::nextLine(bool emptyLineWasDeleted)
+{
+ // verify that the current position is correct
+ assert (peekStart == 0);
+
+ // a deleted line may be replaced if break-blocks is requested
+ // this sets up the compare to check for a replaced empty line
+ if (prevLineDeleted)
+ {
+ prevLineDeleted = false;
+ checkForEmptyLine = true;
+ }
+ if (!emptyLineWasDeleted)
+ prevBuffer = buffer;
+ else
+ prevLineDeleted = true;
+
+ // read the next record
+ buffer.clear();
+ char ch;
+ inStream->get(ch);
+
+ while (!inStream->eof() && ch != '\n' && ch != '\r')
+ {
+ buffer.append(1, ch);
+ inStream->get(ch);
+ }
+
+ if (inStream->eof())
+ {
+ return buffer;
+ }
+
+ int peekCh = inStream->peek();
+
+ // find input end-of-line characters
+ if (!inStream->eof())
+ {
+ if (ch == '\r') // CR+LF is windows otherwise Mac OS 9
+ {
+ if (peekCh == '\n')
+ {
+ inStream->get(ch);
+ eolWindows++;
+ }
+ else
+ eolMacOld++;
+ }
+ else // LF is Linux, allow for improbable LF/CR
+ {
+ if (peekCh == '\r')
+ {
+ inStream->get(ch);
+ eolWindows++;
+ }
+ else
+ eolLinux++;
+ }
+ }
+ else
+ {
+ inStream->clear();
+ }
+
+ // set output end of line characters
+ if (eolWindows >= eolLinux)
+ {
+ if (eolWindows >= eolMacOld)
+ strcpy(outputEOL, "\r\n"); // Windows (CR+LF)
+ else
+ strcpy(outputEOL, "\r"); // MacOld (CR)
+ }
+ else if (eolLinux >= eolMacOld)
+ strcpy(outputEOL, "\n"); // Linux (LF)
+ else
+ strcpy(outputEOL, "\r"); // MacOld (CR)
+
+ return buffer;
+}
+
+// save the current position and get the next line
+// this can be called for multiple reads
+// when finished peeking you MUST call peekReset()
+// call this function from ASFormatter ONLY
+//template<typename T>
+string ASStreamIterator::peekNextLine()
+{
+ assert (hasMoreLines());
+ string nextLine;
+ char ch;
+
+ if (peekStart == 0)
+ peekStart = inStream->tellg();
+
+ // read the next record
+ inStream->get(ch);
+ while (!inStream->eof() && ch != '\n' && ch != '\r')
+ {
+ nextLine.append(1, ch);
+ inStream->get(ch);
+ }
+
+ if (inStream->eof())
+ {
+ return nextLine;
+ }
+
+ int peekCh = inStream->peek();
+
+ // remove end-of-line characters
+ if (!inStream->eof())
+ {
+ if ((peekCh == '\n' || peekCh == '\r') && peekCh != ch) ///////////// changed //////////
+ inStream->get(ch);
+ }
+
+ return nextLine;
+}
+
+// reset current position and EOF for peekNextLine()
+//template<typename T>
+void ASStreamIterator::peekReset()
+{
+ assert(peekStart != 0);
+ inStream->clear();
+ inStream->seekg(peekStart);
+ peekStart = 0;
+}
+
+}
diff --git a/support/highlight/src/core/astyle/ASStreamIterator.h b/support/highlight/src/core/astyle/ASStreamIterator.h
new file mode 100644
index 0000000000..3065895d8a
--- /dev/null
+++ b/support/highlight/src/core/astyle/ASStreamIterator.h
@@ -0,0 +1,101 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Copyright (C) 2006-2008 by Jim Pattee <jimp03@email.com>
+ * Copyright (C) 1998-2002 by Tal Davidson
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>
+ *
+ * This file is a part of Artistic Style - an indentation and
+ * reformatting tool for C, C++, C# and Java source files.
+ * <http://astyle.sourceforge.net>
+ *
+ * Artistic Style is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Artistic Style is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Artistic Style. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+
+#ifndef ASSTREAMITERATOR_H
+#define ASSTREAMITERATOR_H
+
+#include "astyle.h"
+#include <iostream>
+
+namespace astyle
+{
+
+class ASStreamIterator : public ASSourceIterator
+{
+ public:
+ bool checkForEmptyLine;
+
+ // function declarations
+ ASStreamIterator(istream *in);
+ virtual ~ASStreamIterator();
+ string nextLine(bool emptyLineWasDeleted);
+ string peekNextLine();
+ void peekReset();
+ void saveLastInputLine();
+
+ // inline functions
+ bool compareToInputBuffer(const string &nextLine) const { return nextLine == prevBuffer; }
+ const char* getOutputEOL() const { return outputEOL; }
+ bool hasMoreLines() const { return !inStream->eof(); }
+
+ private:
+ istream * inStream; // pointer to the input stream
+ string buffer; // current input line
+ string prevBuffer; // previous input line
+ int eolWindows; // number of Windows line endings (CRLF)
+ int eolLinux; // number of Linux line endings (LF)
+ int eolMacOld; // number of old Mac line endings (CR)
+ int peekStart; // starting position for peekNextLine()
+ char outputEOL[4]; // output end of line char
+ bool prevLineDeleted; // the previous input line was deleted
+};
+
+/*
+
+// typename will be istringstream for GUI and istream otherwise
+//template<typename T>
+class ASStreamIterator :
+ public ASSourceIterator
+{
+ public:
+ // function declarations
+ ASStreamIterator(istream *in);
+ virtual ~ASStreamIterator();
+ string nextLine();
+ string peekNextLine();
+ void peekReset();
+ void saveLastInputLine();
+
+ // inline functions
+ bool compareToInputBuffer(const string &nextLine) const { return nextLine == prevBuffer; }
+ const char* getOutputEOL() const { return outputEOL; }
+ bool hasMoreLines() const { return !inStream->eof(); }
+
+ private:
+ istream* inStream; // pointer to the input stream
+ string buffer; // current input line
+ string prevBuffer; // previous input line
+ int eolWindows; // number of Windows line endings (CRLF)
+ int eolLinux; // number of Linux line endings (LF)
+ int eolMacOld; // number of old Mac line endings (CR)
+ char outputEOL[4]; // output end of line char
+ int peekStart; // starting position for peekNextLine()
+};
+*/
+}
+
+#endif
diff --git a/support/highlight/src/core/astyle/astyle.h b/support/highlight/src/core/astyle/astyle.h
new file mode 100644
index 0000000000..d3a7c3174d
--- /dev/null
+++ b/support/highlight/src/core/astyle/astyle.h
@@ -0,0 +1,802 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Copyright (C) 2006-2010 by Jim Pattee <jimp03@email.com>
+ * Copyright (C) 1998-2002 by Tal Davidson
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>
+ *
+ * This file is a part of Artistic Style - an indentation and
+ * reformatting tool for C, C++, C# and Java source files.
+ * <http://astyle.sourceforge.net>
+ *
+ * Artistic Style is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Artistic Style is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Artistic Style. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+#ifndef ASTYLE_H
+#define ASTYLE_H
+
+#ifdef __VMS
+#define __USE_STD_IOSTREAM 1
+#include <assert>
+#else
+#include <cassert>
+#endif
+
+#include <string.h> // need both string and string.h for GCC
+#include <string>
+#include <vector>
+#include <cctype>
+
+#ifdef _WIN32
+#define STDCALL __stdcall
+#define EXPORT __declspec(dllexport)
+#else
+#define STDCALL
+#define EXPORT
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4996) // secure version deprecation warnings
+#pragma warning(disable: 4267) // 64 bit signed/unsigned loss of data
+#endif
+
+#ifdef __BORLANDC__
+#pragma warn -aus // variable is assigned a value that is never used in function.
+#endif
+
+#ifdef __INTEL_COMPILER
+#pragma warning(disable: 383) // value copied to temporary, reference to temporary used
+#pragma warning(disable: 444) // destructor for base class is not virtual
+#pragma warning(disable: 981) // operands are evaluated in unspecified order
+#endif
+
+using namespace std;
+
+namespace astyle
+{
+
+enum FileType { C_TYPE=0, JAVA_TYPE=1, SHARP_TYPE=2 };
+
+/* The enums below are not recognized by 'vectors' in Microsoft Visual C++
+ V5 when they are part of a namespace!!! Use Visual C++ V6 or higher.
+*/
+enum FormatStyle { STYLE_NONE,
+ STYLE_ALLMAN,
+ STYLE_JAVA,
+ STYLE_KandR,
+ STYLE_STROUSTRUP,
+ STYLE_WHITESMITH,
+ STYLE_BANNER,
+ STYLE_GNU,
+ STYLE_LINUX,
+ STYLE_HORSTMANN,
+ STYLE_1TBS
+ };
+
+enum BracketMode { NONE_MODE,
+ ATTACH_MODE,
+ BREAK_MODE,
+ LINUX_MODE,
+ STROUSTRUP_MODE,
+ HORSTMANN_MODE,
+ BDAC_MODE = LINUX_MODE
+ };
+
+enum BracketType { NULL_TYPE = 0,
+ NAMESPACE_TYPE = 1, // also a DEFINITION_TYPE
+ CLASS_TYPE = 2, // also a DEFINITION_TYPE
+ STRUCT_TYPE = 4, // also a DEFINITION_TYPE
+ INTERFACE_TYPE = 8, // also a DEFINITION_TYPE
+ DEFINITION_TYPE = 16,
+ COMMAND_TYPE = 32,
+ ARRAY_NIS_TYPE = 64, // also an ARRAY_TYPE
+ ARRAY_TYPE = 128, // arrays and enums
+ EXTERN_TYPE = 256, // extern "C". not a command type extern
+ SINGLE_LINE_TYPE = 512
+ };
+
+enum PointerAlign { ALIGN_NONE,
+ ALIGN_TYPE,
+ ALIGN_MIDDLE,
+ ALIGN_NAME
+ };
+
+enum FileEncoding { ENCODING_OK,
+ UTF_16BE,
+ UTF_16LE,
+ UTF_32BE,
+ UTF_32LE
+ };
+
+enum LineEndFormat { LINEEND_DEFAULT, // Use line break that matches most of the file
+ LINEEND_WINDOWS,
+ LINEEND_LINUX,
+ LINEEND_MACOLD,
+ LINEEND_CRLF = LINEEND_WINDOWS,
+ LINEEND_LF = LINEEND_LINUX,
+ LINEEND_CR = LINEEND_MACOLD
+ };
+
+
+//----------------------------------------------------------------------------
+// Class ASSourceIterator
+// A pure virtual class is used by ASFormatter and ASBeautifier instead of
+// ASStreamIterator. This allows programs using AStyle as a plugin to define
+// their own ASStreamIterator. The ASStreamIterator class must inherit
+// this class.
+//----------------------------------------------------------------------------
+
+class ASSourceIterator
+{
+ public:
+ ASSourceIterator() {}
+ virtual ~ASSourceIterator() {}
+ virtual bool hasMoreLines() const = 0;
+ virtual string nextLine(bool emptyLineWasDeleted = false) = 0;
+ virtual string peekNextLine() = 0;
+ virtual void peekReset() = 0;
+};
+
+//----------------------------------------------------------------------------
+// Class ASResource
+//----------------------------------------------------------------------------
+
+class ASResource
+{
+ public:
+ void buildAssignmentOperators(vector<const string*>* assignmentOperators);
+ void buildCastOperators(vector<const string*>* castOperators);
+ void buildHeaders(vector<const string*>* headers, int fileType, bool beautifier=false);
+ void buildIndentableHeaders(vector<const string*>* indentableHeaders);
+ void buildNonAssignmentOperators(vector<const string*>* nonAssignmentOperators);
+ void buildNonParenHeaders(vector<const string*>* nonParenHeaders, int fileType, bool beautifier=false);
+ void buildOperators(vector<const string*>* operators);
+ void buildPreBlockStatements(vector<const string*>* preBlockStatements, int fileType);
+ void buildPreCommandHeaders(vector<const string*>* preCommandHeaders, int fileType);
+ void buildPreDefinitionHeaders(vector<const string*>* preDefinitionHeaders, int fileType);
+
+ public:
+ static const string AS_IF, AS_ELSE;
+ static const string AS_DO, AS_WHILE;
+ static const string AS_FOR;
+ static const string AS_SWITCH, AS_CASE, AS_DEFAULT;
+ static const string AS_TRY, AS_CATCH, AS_THROWS, AS_FINALLY;
+ static const string AS_PUBLIC, AS_PROTECTED, AS_PRIVATE;
+ static const string AS_CLASS, AS_STRUCT, AS_UNION, AS_INTERFACE, AS_NAMESPACE;
+ static const string AS_EXTERN, AS_ENUM;
+ static const string AS_STATIC, AS_CONST, AS_WHERE, AS_NEW;
+ static const string AS_SYNCHRONIZED;
+ static const string AS_OPERATOR, AS_TEMPLATE;
+ static const string AS_OPEN_BRACKET, AS_CLOSE_BRACKET;
+ static const string AS_OPEN_LINE_COMMENT, AS_OPEN_COMMENT, AS_CLOSE_COMMENT;
+ static const string AS_BAR_DEFINE, AS_BAR_INCLUDE, AS_BAR_IF, AS_BAR_EL, AS_BAR_ENDIF;
+ static const string AS_RETURN;
+ static const string AS_CIN, AS_COUT, AS_CERR;
+ static const string AS_ASSIGN, AS_PLUS_ASSIGN, AS_MINUS_ASSIGN, AS_MULT_ASSIGN;
+ static const string AS_DIV_ASSIGN, AS_MOD_ASSIGN, AS_XOR_ASSIGN, AS_OR_ASSIGN, AS_AND_ASSIGN;
+ static const string AS_GR_GR_ASSIGN, AS_LS_LS_ASSIGN, AS_GR_GR_GR_ASSIGN, AS_LS_LS_LS_ASSIGN;
+ static const string AS_GCC_MIN_ASSIGN, AS_GCC_MAX_ASSIGN;
+ static const string AS_EQUAL, AS_PLUS_PLUS, AS_MINUS_MINUS, AS_NOT_EQUAL, AS_GR_EQUAL, AS_GR_GR_GR, AS_GR_GR;
+ static const string AS_LS_EQUAL, AS_LS_LS_LS, AS_LS_LS;
+ static const string AS_QUESTION_QUESTION, AS_EQUAL_GR;
+ static const string AS_ARROW, AS_AND, AS_OR;
+ static const string AS_COLON_COLON, AS_PAREN_PAREN, AS_BLPAREN_BLPAREN;
+ static const string AS_PLUS, AS_MINUS, AS_MULT, AS_DIV, AS_MOD, AS_GR, AS_LS;
+ static const string AS_NOT, AS_BIT_XOR, AS_BIT_OR, AS_BIT_AND, AS_BIT_NOT;
+ static const string AS_QUESTION, AS_COLON, AS_SEMICOLON, AS_COMMA;
+ static const string AS_ASM, AS__ASM__, AS_MS_ASM, AS_MS__ASM;
+ static const string AS_FOREACH, AS_LOCK, AS_UNSAFE, AS_FIXED;
+ static const string AS_GET, AS_SET, AS_ADD, AS_REMOVE;
+ static const string AS_DELEGATE, AS_UNCHECKED;
+ static const string AS_CONST_CAST, AS_DYNAMIC_CAST, AS_REINTERPRET_CAST, AS_STATIC_CAST;
+}; // Class ASResource
+
+//----------------------------------------------------------------------------
+// Class ASBase
+//----------------------------------------------------------------------------
+
+class ASBase
+{
+ private:
+ // all variables should be set by the "init" function
+ int baseFileType; // a value from enum FileType
+
+ protected:
+ ASBase() { baseFileType = C_TYPE; }
+ ~ASBase() {}
+
+ // functions definitions are at the end of ASResource.cpp
+ bool findKeyword(const string &line, int i, const string &keyword) const;
+ string getCurrentWord(const string& line, size_t index) const;
+
+ protected:
+
+ void init(int fileTypeArg) { baseFileType = fileTypeArg; }
+ bool isCStyle() const { return (baseFileType == C_TYPE); }
+ bool isJavaStyle() const { return (baseFileType == JAVA_TYPE); }
+ bool isSharpStyle() const { return (baseFileType == SHARP_TYPE); }
+
+ // check if a specific character can be used in a legal variable/method/class name
+ bool isLegalNameChar(char ch) const {
+ if (isWhiteSpace(ch)) return false;
+ if ((unsigned) ch > 127) return false;
+ return (isalnum(ch)
+ || ch == '.' || ch == '_'
+ || (isJavaStyle() && ch == '$')
+ || (isSharpStyle() && ch == '@')); // may be used as a prefix
+ }
+
+ // check if a specific character can be part of a header
+ bool isCharPotentialHeader(const string &line, size_t i) const {
+ assert(!isWhiteSpace(line[i]));
+ char prevCh = ' ';
+ if (i > 0) prevCh = line[i-1];
+ if (!isLegalNameChar(prevCh) && isLegalNameChar(line[i]))
+ return true;
+ return false;
+ }
+
+ // check if a specific character can be part of an operator
+ bool isCharPotentialOperator(char ch) const {
+ assert(!isWhiteSpace(ch));
+ if ((unsigned) ch > 127) return false;
+ return (ispunct(ch)
+ && ch != '{' && ch != '}'
+ && ch != '(' && ch != ')'
+ && ch != '[' && ch != ']'
+ && ch != ';' && ch != ','
+ && ch != '#' && ch != '\\'
+ && ch != '\'' && ch != '\"');
+ }
+
+ // check if a specific character is a whitespace character
+ bool isWhiteSpace(char ch) const { return (ch == ' ' || ch == '\t'); }
+
+ // peek at the next unread character.
+ char peekNextChar(const string &line, int i) const {
+ char ch = ' ';
+ size_t peekNum = line.find_first_not_of(" \t", i + 1);
+ if (peekNum == string::npos)
+ return ch;
+ ch = line[peekNum];
+ return ch;
+ }
+}; // Class ASBase
+
+//----------------------------------------------------------------------------
+// Class ASBeautifier
+//----------------------------------------------------------------------------
+
+class ASBeautifier : protected ASResource, protected ASBase
+{
+ public:
+ ASBeautifier();
+ virtual ~ASBeautifier();
+ virtual void init(ASSourceIterator* iter);
+ void init();
+ virtual bool hasMoreLines() const;
+ virtual string nextLine();
+ virtual string beautify(const string &line);
+ void deleteVector(vector<const string*>*& container);
+ void initVector(vector<const string*>*& container);
+ void setTabIndentation(int length = 4, bool forceTabs = false);
+ void setSpaceIndentation(int length = 4);
+ void setMaxInStatementIndentLength(int max);
+ void setMinConditionalIndentLength(int min);
+ void setIndentManuallySet(bool state);
+ void setMinConditionalManuallySet(bool state);
+ void setModeManuallySet(bool state);
+ void setClassIndent(bool state);
+ void setSwitchIndent(bool state);
+ void setCaseIndent(bool state);
+ void setBracketIndent(bool state);
+ void setBlockIndent(bool state);
+ void setNamespaceIndent(bool state);
+ void setLabelIndent(bool state);
+ void setCStyle();
+ void setJavaStyle();
+ void setSharpStyle();
+ void setEmptyLineFill(bool state);
+ void setPreprocessorIndent(bool state);
+ int getFileType();
+ int getIndentLength(void);
+ string getIndentString(void);
+ bool getBracketIndent(void);
+ bool getBlockIndent(void);
+ bool getCaseIndent(void);
+ bool getClassIndent(void);
+ bool getEmptyLineFill(void);
+ bool getForceTabIndentation(void);
+ bool getIndentManuallySet(void);
+ bool getMinConditionalManuallySet(void);
+ bool getModeManuallySet(void);
+ bool getSwitchIndent(void);
+
+ protected:
+ void deleteStaticVectors();
+ const string* findHeader(const string &line, int i,
+ const vector<const string*>* possibleHeaders) const;
+ const string* findOperator(const string &line, int i,
+ const vector<const string*>* possibleOperators) const;
+ int getNextProgramCharDistance(const string &line, int i) const;
+ int indexOf(vector<const string*> &container, const string *element);
+ string trim(const string &str);
+
+ // variables set by ASFormatter - must be updated in activeBeautifierStack
+ int inLineNumber;
+ int horstmannIndentInStatement;
+ int nonInStatementBracket;
+ bool lineCommentNoBeautify;
+ bool isNonInStatementArray;
+ bool isSharpAccessor;
+ bool isSharpDelegate;
+ bool isInExtern;
+ bool isInBeautifySQL;
+ bool isInIndentableStruct;
+
+ private:
+ ASBeautifier(const ASBeautifier &copy);
+ ASBeautifier& operator=(ASBeautifier&); // not to be implemented
+
+ void initStatic();
+ void registerInStatementIndent(const string &line, int i, int spaceTabCount,
+ int tabIncrementIn, int minIndent, bool updateParenStack);
+ string preLineWS(int spaceTabCount, int tabCount);
+
+ static int beautifierFileType;
+ static vector<const string*>* headers;
+ static vector<const string*>* nonParenHeaders;
+ static vector<const string*>* preBlockStatements;
+ static vector<const string*>* assignmentOperators;
+ static vector<const string*>* nonAssignmentOperators;
+ static vector<const string*>* indentableHeaders;
+
+ ASSourceIterator *sourceIterator;
+ vector<ASBeautifier*> *waitingBeautifierStack;
+ vector<ASBeautifier*> *activeBeautifierStack;
+ vector<int> *waitingBeautifierStackLengthStack;
+ vector<int> *activeBeautifierStackLengthStack;
+ vector<const string*> *headerStack;
+ vector< vector<const string*>* > *tempStacks;
+ vector<int> *blockParenDepthStack;
+ vector<bool> *blockStatementStack;
+ vector<bool> *parenStatementStack;
+ vector<bool> *bracketBlockStateStack;
+ vector<int> *inStatementIndentStack;
+ vector<int> *inStatementIndentStackSizeStack;
+ vector<int> *parenIndentStack;
+ int convertTabToSpaces(int i, int tabIncrementIn) const;
+ int getInStatementIndentAssign(const string& line, size_t currPos) const;
+ int getInStatementIndentComma(const string& line, size_t currPos) const;
+ bool isClassAccessModifier(string& line) const;
+ bool isLineEndComment(string& line, int startPos) const;
+ bool statementEndsWithComma(string &line, int index);
+ vector<vector<const string*>*>* copyTempStacks(const ASBeautifier &other) const;
+ template<typename T> void deleteContainer(T &container);
+ void deleteContainer(vector<vector<const string*>*>* &container);
+ template<typename T> void initContainer(T &container, T value);
+
+ private: // variables
+ string indentString;
+ const string *currentHeader;
+ const string *previousLastLineHeader;
+ const string *probationHeader;
+ bool isInQuote;
+ bool isInVerbatimQuote;
+ bool haveLineContinuationChar;
+ bool isInAsm;
+ bool isInAsmOneLine;
+ bool isInAsmBlock;
+ bool isInComment;
+ bool isInHorstmannComment;
+ bool isInCase;
+ bool isInQuestion;
+ bool isInStatement;
+ bool isInHeader;
+ bool isInTemplate;
+ bool isInDefine;
+ bool isInDefineDefinition;
+ bool classIndent;
+ bool isInClassInitializer;
+ bool isInClassHeaderTab;
+ bool isInEnum;
+ bool switchIndent;
+ bool caseIndent;
+ bool namespaceIndent;
+ bool bracketIndent;
+ bool blockIndent;
+ bool labelIndent;
+ bool preprocessorIndent;
+ bool isInConditional;
+ bool isIndentManuallySet;
+ bool isMinConditionalManuallySet;
+ bool isModeManuallySet;
+ bool shouldForceTabIndentation;
+ bool emptyLineFill;
+ bool backslashEndsPrevLine;
+ bool lineOpensComment;
+ bool blockCommentNoIndent;
+ bool blockCommentNoBeautify;
+ bool previousLineProbationTab;
+ int fileType;
+ int minConditionalIndent;
+ int parenDepth;
+ int indentLength;
+ int blockTabCount;
+ int maxInStatementIndent;
+ int classInitializerTabs;
+ int templateDepth;
+ int prevFinalLineSpaceTabCount;
+ int prevFinalLineTabCount;
+ int defineTabCount;
+ char quoteChar;
+ char prevNonSpaceCh;
+ char currentNonSpaceCh;
+ char currentNonLegalCh;
+ char prevNonLegalCh;
+}; // Class ASBeautifier
+
+//----------------------------------------------------------------------------
+// Class ASEnhancer
+//----------------------------------------------------------------------------
+
+class ASEnhancer : protected ASBase
+{
+ public: // functions
+ ASEnhancer();
+ ~ASEnhancer();
+ void init(int, int, string, bool, bool);
+ void enhance(string &line, bool isInSQL);
+
+ private:
+ // options from command line or options file
+ int indentLength;
+ bool useTabs;
+ bool caseIndent;
+ bool emptyLineFill;
+
+ // parsing variables
+ int lineNumber;
+ bool isInQuote;
+ bool isInComment;
+ char quoteChar;
+
+ // unindent variables
+ int bracketCount;
+ int switchDepth;
+ bool lookingForCaseBracket;
+ bool unindentNextLine;
+
+ // struct used by ParseFormattedLine function
+ // contains variables used to unindent the case blocks
+ struct switchVariables {
+ int switchBracketCount;
+ int unindentDepth;
+ bool unindentCase;
+ };
+
+ switchVariables sw; // switch variables struct
+ vector<switchVariables> swVector; // stack vector of switch variables
+
+ // event table variables
+ bool nextLineIsEventIndent; // begin event table indent is reached
+ bool isInEventTable; // need to indent an event table
+
+ // SQL variables
+ bool nextLineIsDeclareIndent; // begin declare section indent is reached
+ bool isInDeclareSection; // need to indent a declare section
+
+
+ private: // functions
+ size_t findCaseColon(string &line, size_t caseIndex) const;
+ int indentLine(string &line, int indent) const;
+ bool isBeginDeclareSectionSQL(string &line, size_t index) const;
+ bool isEndDeclareSectionSQL(string &line, size_t index) const;
+ size_t processSwitchBlock(string &line, size_t index);
+ int unindentLine(string &line, int unindent) const;
+}; // Class ASEnhancer
+
+//----------------------------------------------------------------------------
+// Class ASFormatter
+//----------------------------------------------------------------------------
+
+class ASFormatter : public ASBeautifier
+{
+ public: // functions
+ ASFormatter();
+ virtual ~ASFormatter();
+ virtual void init(ASSourceIterator* iter);
+ virtual bool hasMoreLines() const;
+ virtual string nextLine();
+ LineEndFormat getLineEndFormat() const;
+ void setFormattingStyle(FormatStyle style);
+ void setAddBracketsMode(bool state);
+ void setAddOneLineBracketsMode(bool state);
+ void setBracketFormatMode(BracketMode mode);
+ void setBreakClosingHeaderBracketsMode(bool state);
+ void setBreakBlocksMode(bool state);
+ void setBreakClosingHeaderBlocksMode(bool state);
+ void setBreakElseIfsMode(bool state);
+ void setBreakOneLineBlocksMode(bool state);
+ void setDeleteEmptyLinesMode(bool state);
+ void setIndentCol1CommentsMode(bool state);
+ void setLineEndFormat(LineEndFormat fmt);
+ void setOperatorPaddingMode(bool mode);
+ void setParensOutsidePaddingMode(bool mode);
+ void setParensInsidePaddingMode(bool mode);
+ void setParensHeaderPaddingMode(bool mode);
+ void setParensUnPaddingMode(bool state);
+ void setPointerAlignment(PointerAlign alignment);
+ void setSingleStatementsMode(bool state);
+ void setTabSpaceConversionMode(bool state);
+
+ private: // functions
+ void ASformatter(ASFormatter &copy); // not to be imlpemented
+ ASFormatter& operator=(ASFormatter&); // not to be implemented
+ template<typename T> void deleteContainer(T &container);
+ template<typename T> void initContainer(T &container, T value);
+ char peekNextChar() const;
+ BracketType getBracketType();
+ bool addBracketsToStatement();
+ bool commentAndHeaderFollows() const;
+ bool getNextChar();
+ bool getNextLine(bool emptyLineWasDeleted = false);
+ bool isBeforeComment() const;
+ bool isBeforeAnyComment() const;
+ bool isBeforeAnyLineEndComment(int startPos) const;
+ bool isBeforeMultipleLineEndComments(int startPos) const;
+ bool isBracketType(BracketType a, BracketType b) const;
+ bool isCurrentBracketBroken() const;
+ bool isDereferenceOrAddressOf() const;
+ bool isExecSQL(string &line, size_t index) const;
+ bool isEmptyLine(const string &line) const;
+ bool isNextWordSharpNonParenHeader(int startChar) const;
+ bool isNonInStatementArrayBracket() const;
+ bool isPointerOrReference() const;
+ bool isPointerOrReferenceCentered() const;
+ bool isSharpStyleWithParen(const string* header) const;
+ bool isStructAccessModified(string &firstLine, size_t index) const;
+ bool isUnaryOperator() const;
+ bool isInExponent() const;
+ bool isOneLineBlockReached(string& line, int startChar) const;
+ bool isNextCharOpeningBracket(int startChar) const;
+ bool isOkToBreakBlock(BracketType bracketType) const;
+ int getCurrentLineCommentAdjustment();
+ int getNextLineCommentAdjustment();
+ void appendCharInsideComments();
+ void appendSequence(const string &sequence, bool canBreakLine = true);
+ void appendSpacePad();
+ void appendSpaceAfter();
+ void breakLine();
+ void buildLanguageVectors();
+ void checkForFollowingHeader(const string& firstLine);
+ void convertTabToSpaces();
+ void deleteContainer(vector<BracketType>* &container);
+ void formatArrayRunIn();
+ void formatRunIn();
+ void goForward(int i);
+ void initContainer(vector<BracketType>* &container, vector<BracketType>* value);
+ void initNewLine();
+ void padOperators(const string *newOperator);
+ void padParens();
+ void formatArrayBrackets(BracketType bracketType, bool isOpeningArrayBracket);
+ void formatClosingBracket(BracketType bracketType);
+ void formatCommentBody();
+ void formatCommentOpener();
+ void formatLineCommentBody();
+ void formatLineCommentOpener();
+ void formatOpeningBracket(BracketType bracketType);
+ void formatQuoteBody();
+ void formatQuoteOpener();
+ void formatPointerOrReference();
+ void formatPointerOrReferenceCast();
+ void adjustComments();
+ void isLineBreakBeforeClosingHeader();
+ void setBreakBlocksVariables();
+ void fixOptionVariableConflicts();
+ void processPreprocessor();
+ void trimContinuationLine();
+ size_t findNextChar(string& line, char searchChar, int searchStart = 0);
+ string getPreviousWord(const string& line, int currPos) const;
+ string peekNextText(const string& firstLine, bool endOnEmptyLine=false) const;
+
+ private: // variables
+ static int formatterFileType;
+ static vector<const string*>* headers;
+ static vector<const string*>* nonParenHeaders;
+ static vector<const string*>* preDefinitionHeaders;
+ static vector<const string*>* preCommandHeaders;
+ static vector<const string*>* operators;
+ static vector<const string*>* assignmentOperators;
+ static vector<const string*>* castOperators;
+
+ ASSourceIterator *sourceIterator;
+ ASEnhancer *enhancer;
+
+ vector<const string*> *preBracketHeaderStack;
+ vector<BracketType> *bracketTypeStack;
+ vector<int> *parenStack;
+ vector<bool> *structStack;
+ string readyFormattedLine;
+ string currentLine;
+ string formattedLine;
+ const string *currentHeader;
+ const string *previousOperator; // used ONLY by pad-oper
+ char currentChar;
+ char previousChar;
+ char previousNonWSChar;
+ char previousCommandChar;
+ char quoteChar;
+ int charNum;
+ int preprocBracketTypeStackSize;
+ int tabIncrementIn;
+ int spacePadNum;
+ int nextLineSpacePadNum;
+ int templateDepth;
+ int traceLineNumber;
+ int horstmannIndentChars;
+ size_t leadingSpaces;
+ size_t formattedLineCommentNum; // comment location on formattedLine
+ size_t currentLineFirstBracketNum; // first bracket location on currentLine
+ size_t previousReadyFormattedLineLength;
+ FormatStyle formattingStyle;
+ BracketMode bracketFormatMode;
+ BracketType previousBracketType;
+ PointerAlign pointerAlignment;
+ LineEndFormat lineEnd;
+ bool isVirgin;
+ bool shouldPadOperators;
+ bool shouldPadParensOutside;
+ bool shouldPadParensInside;
+ bool shouldPadHeader;
+ bool shouldUnPadParens;
+ bool shouldConvertTabs;
+ bool shouldIndentCol1Comments;
+ bool isInLineComment;
+ bool isInComment;
+ bool noTrimCommentContinuation;
+ bool isInPreprocessor;
+ bool isInTemplate;
+ bool doesLineStartComment;
+ bool lineEndsInCommentOnly;
+ bool lineIsLineCommentOnly;
+ bool lineIsEmpty;
+ bool isImmediatelyPostCommentOnly;
+ bool isImmediatelyPostEmptyLine;
+ bool isInQuote;
+ bool isInVerbatimQuote;
+ bool haveLineContinuationChar;
+ bool isInQuoteContinuation;
+ bool isInBlParen;
+ bool isSpecialChar;
+ bool isNonParenHeader;
+ bool foundQuestionMark;
+ bool foundPreDefinitionHeader;
+ bool foundNamespaceHeader;
+ bool foundClassHeader;
+ bool foundStructHeader;
+ bool foundInterfaceHeader;
+ bool foundPreCommandHeader;
+ bool foundCastOperator;
+ bool isInLineBreak;
+ bool endOfCodeReached;
+ bool lineCommentNoIndent;
+ bool isInExecSQL;
+ bool isInAsm;
+ bool isInAsmOneLine;
+ bool isInAsmBlock;
+ bool isLineReady;
+ bool isPreviousBracketBlockRelated;
+ bool isInPotentialCalculation;
+ bool isCharImmediatelyPostComment;
+ bool isPreviousCharPostComment;
+ bool isCharImmediatelyPostLineComment;
+ bool isCharImmediatelyPostOpenBlock;
+ bool isCharImmediatelyPostCloseBlock;
+ bool isCharImmediatelyPostTemplate;
+ bool isCharImmediatelyPostReturn;
+ bool isCharImmediatelyPostOperator;
+ bool breakCurrentOneLineBlock;
+ bool isInHorstmannRunIn;
+ bool currentLineBeginsWithBracket;
+ bool shouldBreakOneLineBlocks;
+ bool shouldReparseCurrentChar;
+ bool shouldBreakOneLineStatements;
+ bool shouldBreakClosingHeaderBrackets;
+ bool shouldBreakElseIfs;
+ bool shouldAddBrackets;
+ bool shouldAddOneLineBrackets;
+ bool shouldDeleteEmptyLines;
+ bool needHeaderOpeningBracket;
+ bool shouldBreakLineAtNextChar;
+ bool passedSemicolon;
+ bool passedColon;
+ bool clearNonInStatement;
+ bool isImmediatelyPostComment;
+ bool isImmediatelyPostLineComment;
+ bool isImmediatelyPostEmptyBlock;
+ bool isImmediatelyPostPreprocessor;
+ bool isImmediatelyPostReturn;
+ bool isImmediatelyPostOperator;
+
+ bool shouldBreakBlocks;
+ bool shouldBreakClosingHeaderBlocks;
+ bool isPrependPostBlockEmptyLineRequested;
+ bool isAppendPostBlockEmptyLineRequested;
+
+ bool prependEmptyLine;
+ bool appendOpeningBracket;
+ bool foundClosingHeader;
+
+ bool isInHeader;
+ bool isImmediatelyPostHeader;
+ bool isInCase;
+ bool isJavaStaticConstructor;
+
+ private: // inline functions
+ // append a character to the current formatted line.
+ void appendChar(char ch, bool canBreakLine) {
+ if (canBreakLine && isInLineBreak)
+ breakLine();
+ formattedLine.append(1, ch);
+ isImmediatelyPostCommentOnly = false;
+ }
+
+ // append the CURRENT character (curentChar) to the current formatted line.
+ void appendCurrentChar(bool canBreakLine = true) {
+ appendChar(currentChar, canBreakLine);
+ }
+
+ // check if a specific sequence exists in the current placement of the current line
+ bool isSequenceReached(const char *sequence) const {
+ return currentLine.compare(charNum, strlen(sequence), sequence) == 0;
+ }
+
+ // call ASBase::findHeader for the current character
+ const string *findHeader(const vector<const string*>* headers) {
+ return ASBeautifier::findHeader(currentLine, charNum, headers);
+ }
+
+ // call ASBase::findOperator for the current character
+ const string *findOperator(const vector<const string*>* headers) {
+ return ASBeautifier::findOperator(currentLine, charNum, headers);
+ }
+}; // Class ASFormatter
+
+
+//----------------------------------------------------------------------------
+// astyle namespace global declarations
+//----------------------------------------------------------------------------
+// sort comparison functions for ASResource
+bool sortOnLength(const string *a, const string *b);
+bool sortOnName(const string *a, const string *b);
+
+} // end of astyle namespace
+
+// end of astyle namespace --------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+// declarations for library build
+// global because they are called externally and are NOT part of the namespace
+//----------------------------------------------------------------------------
+
+typedef void (STDCALL *fpError)(int, char*); // pointer to callback error handler
+typedef char* (STDCALL *fpAlloc)(unsigned long); // pointer to callback memory allocation
+extern "C" EXPORT char* STDCALL AStyleMain(const char*, const char*, fpError, fpAlloc);
+extern "C" EXPORT const char* STDCALL AStyleGetVersion (void);
+
+
+#endif // closes ASTYLE_H
diff --git a/support/highlight/src/core/astyle/astyle_main.cpp b/support/highlight/src/core/astyle/astyle_main.cpp
new file mode 100644
index 0000000000..5b8a0b7e3a
--- /dev/null
+++ b/support/highlight/src/core/astyle/astyle_main.cpp
@@ -0,0 +1,2535 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Copyright (C) 2006-2010 by Jim Pattee <jimp03@email.com>
+ * Copyright (C) 1998-2002 by Tal Davidson
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>
+ *
+ * This file is a part of Artistic Style - an indentation and
+ * reformatting tool for C, C++, C# and Java source files.
+ * <http://astyle.sourceforge.net>
+ *
+ * Artistic Style is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Artistic Style is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Artistic Style. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+#include "astyle_main.h"
+
+#include <algorithm>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <cstdlib>
+#include <errno.h>
+
+// includes for recursive getFileNames() function
+#ifdef _WIN32
+#undef UNICODE // use ASCII windows functions
+#include <windows.h>
+#else
+#include <dirent.h>
+#include <sys/stat.h>
+#ifdef __VMS
+#include <unixlib.h>
+#include <rms.h>
+#include <ssdef.h>
+#include <stsdef.h>
+#include <lib$routines.h>
+#include <starlet.h>
+#endif /* __VMS */
+#endif
+
+// turn off MinGW automatic file globbing
+// this CANNOT be in the astyle namespace
+int _CRT_glob = 0;
+
+namespace astyle
+{
+
+#define IS_OPTION(arg,op) ((arg).compare(op)==0)
+#define IS_OPTIONS(arg,a,b) (IS_OPTION((arg),(a)) || IS_OPTION((arg),(b)))
+
+#define GET_PARAM(arg,op) ((arg).substr(strlen(op)))
+#define GET_PARAMS(arg,a,b) (isParamOption((arg),(a)) ? GET_PARAM((arg),(a)) : GET_PARAM((arg),(b)))
+
+#ifdef _WIN32
+char g_fileSeparator = '\\';
+bool g_isCaseSensitive = false;
+#else
+char g_fileSeparator = '/';
+bool g_isCaseSensitive = true;
+#endif
+
+#ifdef ASTYLE_LIB
+// library build variables
+stringstream* _err = NULL;
+#else
+// console build variables
+ostream* _err = &cerr; // direct error messages to cerr
+ASConsole* g_console = NULL; // class to encapsulate console variables
+#endif
+
+#ifdef ASTYLE_JNI
+// java library build variables
+JNIEnv* g_env;
+jobject g_obj;
+jmethodID g_mid;
+#endif
+
+const char* _version = "1.24";
+
+
+/**
+ * parse the options vector
+ * ITER can be either a fileOptionsVector (options file) or an optionsVector (command line)
+ *
+ * @return true if no errors, false if errors
+ */
+template<typename ITER>
+bool parseOptions(ASFormatter &formatter,
+ const ITER &optionsBegin,
+ const ITER &optionsEnd,
+ const string &errorInfo)
+{
+ ITER option;
+ bool ok = true;
+ string arg, subArg;
+
+ for (option = optionsBegin; option != optionsEnd; ++option)
+ {
+ arg = *option;
+
+ if (arg.compare(0, 2, "--") == 0)
+ ok &= parseOption(formatter, arg.substr(2), errorInfo);
+ else if (arg[0] == '-')
+ {
+ size_t i;
+
+ for (i = 1; i < arg.length(); ++i)
+ {
+ if (isalpha(arg[i]) && i > 1)
+ {
+ ok &= parseOption(formatter, subArg, errorInfo);
+ subArg = "";
+ }
+ subArg.append(1, arg[i]);
+ }
+ ok &= parseOption(formatter, subArg, errorInfo);
+ subArg = "";
+ }
+ else
+ {
+ ok &= parseOption(formatter, arg, errorInfo);
+ subArg = "";
+ }
+ }
+ return ok;
+}
+
+void importOptions(istream &in, vector<string> &optionsVector)
+{
+ char ch;
+ string currentToken;
+
+ while (in)
+ {
+ currentToken = "";
+ do
+ {
+ in.get(ch);
+ if (in.eof())
+ break;
+ // treat '#' as line comments
+ if (ch == '#')
+ while (in)
+ {
+ in.get(ch);
+ if (ch == '\n')
+ break;
+ }
+
+ // break options on spaces, tabs, commas, or new-lines
+ if (in.eof() || ch == ' ' || ch == '\t' || ch == ',' || ch == '\n')
+ break;
+ else
+ currentToken.append(1, ch);
+
+ }
+ while (in);
+
+ if (currentToken.length() != 0)
+ optionsVector.push_back(currentToken);
+ }
+}
+
+void isOptionError(const string &arg, const string &errorInfo)
+{
+#ifdef ASTYLE_LIB
+ if (_err->str().length() == 0)
+ {
+ (*_err) << errorInfo << endl; // need main error message
+ (*_err) << arg; // output the option in error
+ }
+ else
+ (*_err) << endl << arg; // put endl after previous option
+#else
+ if (errorInfo.length() > 0) // to avoid a compiler warning
+ g_console->error("Error in param: ", arg.c_str());
+#endif
+}
+
+
+bool isParamOption(const string &arg, const char *option)
+{
+ bool retVal = arg.compare(0, strlen(option), option) == 0;
+ // if comparing for short option, 2nd char of arg must be numeric
+ if (retVal && strlen(option) == 1 && arg.length() > 1)
+ if (!isdigit(arg[1]))
+ retVal = false;
+ return retVal;
+}
+
+bool isParamOption(const string &arg, const char *option1, const char *option2)
+{
+ return isParamOption(arg, option1) || isParamOption(arg, option2);
+}
+
+bool parseOption(ASFormatter &formatter, const string &arg, const string &errorInfo)
+{
+ if ( IS_OPTION(arg, "style=allman") || IS_OPTION(arg, "style=ansi") || IS_OPTION(arg, "style=bsd") )
+ {
+ formatter.setFormattingStyle(STYLE_ALLMAN);
+ }
+ else if ( IS_OPTION(arg, "style=java") )
+ {
+ formatter.setFormattingStyle(STYLE_JAVA);
+ }
+ else if ( IS_OPTION(arg, "style=k&r") || IS_OPTION(arg, "style=k/r") )
+ {
+ formatter.setFormattingStyle(STYLE_KandR);
+ }
+ else if ( IS_OPTION(arg, "style=stroustrup") )
+ {
+ formatter.setFormattingStyle(STYLE_STROUSTRUP);
+ }
+ else if ( IS_OPTION(arg, "style=whitesmith") )
+ {
+ formatter.setFormattingStyle(STYLE_WHITESMITH);
+ }
+ else if ( IS_OPTION(arg, "style=banner") )
+ {
+ formatter.setFormattingStyle(STYLE_BANNER);
+ }
+ else if ( IS_OPTION(arg, "style=gnu") )
+ {
+ formatter.setFormattingStyle(STYLE_GNU);
+ }
+ else if ( IS_OPTION(arg, "style=linux") )
+ {
+ formatter.setFormattingStyle(STYLE_LINUX);
+ }
+ else if ( IS_OPTION(arg, "style=horstmann") )
+ {
+ formatter.setFormattingStyle(STYLE_HORSTMANN);
+ }
+ else if ( IS_OPTION(arg, "style=1tbs") || IS_OPTION(arg, "style=otbs") )
+ {
+ formatter.setFormattingStyle(STYLE_1TBS);
+ }
+ else if ( isParamOption(arg, "A") )
+ {
+ int style = 0;
+ string styleParam = GET_PARAM(arg, "A");
+ if (styleParam.length() > 0)
+ style = atoi(styleParam.c_str());
+ if (style < 1 || style > 10)
+ isOptionError(arg, errorInfo);
+ else if (style == 1)
+ formatter.setFormattingStyle(STYLE_ALLMAN);
+ else if (style == 2)
+ formatter.setFormattingStyle(STYLE_JAVA);
+ else if (style == 3)
+ formatter.setFormattingStyle(STYLE_KandR);
+ else if (style == 4)
+ formatter.setFormattingStyle(STYLE_STROUSTRUP);
+ else if (style == 5)
+ formatter.setFormattingStyle(STYLE_WHITESMITH);
+ else if (style == 6)
+ formatter.setFormattingStyle(STYLE_BANNER);
+ else if (style == 7)
+ formatter.setFormattingStyle(STYLE_GNU);
+ else if (style == 8)
+ formatter.setFormattingStyle(STYLE_LINUX);
+ else if (style == 9)
+ formatter.setFormattingStyle(STYLE_HORSTMANN);
+ else if (style == 10)
+ formatter.setFormattingStyle(STYLE_1TBS);
+ }
+ // must check for mode=cs before mode=c !!!
+ else if ( IS_OPTION(arg, "mode=cs") )
+ {
+ formatter.setSharpStyle();
+ formatter.setModeManuallySet(true);
+ }
+ else if ( IS_OPTION(arg, "mode=c") )
+ {
+ formatter.setCStyle();
+ formatter.setModeManuallySet(true);
+ }
+ else if ( IS_OPTION(arg, "mode=java") )
+ {
+ formatter.setJavaStyle();
+ formatter.setModeManuallySet(true);
+ }
+ else if ( isParamOption(arg, "t", "indent=tab=") )
+ {
+ int spaceNum = 4;
+ string spaceNumParam = GET_PARAMS(arg, "t", "indent=tab=");
+ if (spaceNumParam.length() > 0)
+ spaceNum = atoi(spaceNumParam.c_str());
+ if (spaceNum < 2 || spaceNum > 20)
+ isOptionError(arg, errorInfo);
+ else
+ {
+ formatter.setTabIndentation(spaceNum, false);
+ formatter.setIndentManuallySet(true);
+ }
+ }
+ else if ( IS_OPTION(arg, "indent=tab") )
+ {
+ formatter.setTabIndentation(4);
+ // do NOT call setIndentManuallySet(true);
+ }
+ else if ( isParamOption(arg, "T", "indent=force-tab=") )
+ {
+ int spaceNum = 4;
+ string spaceNumParam = GET_PARAMS(arg, "T", "indent=force-tab=");
+ if (spaceNumParam.length() > 0)
+ spaceNum = atoi(spaceNumParam.c_str());
+ if (spaceNum < 2 || spaceNum > 20)
+ isOptionError(arg, errorInfo);
+ else
+ {
+ formatter.setTabIndentation(spaceNum, true);
+ formatter.setIndentManuallySet(true);
+ }
+ }
+ else if ( IS_OPTION(arg, "indent=force-tab") )
+ {
+ formatter.setTabIndentation(4, true);
+ // do NOT call setIndentManuallySet(true);
+ }
+ else if ( isParamOption(arg, "s", "indent=spaces=") )
+ {
+ int spaceNum = 4;
+ string spaceNumParam = GET_PARAMS(arg, "s", "indent=spaces=");
+ if (spaceNumParam.length() > 0)
+ spaceNum = atoi(spaceNumParam.c_str());
+ if (spaceNum < 2 || spaceNum > 20)
+ isOptionError(arg, errorInfo);
+ else
+ {
+ formatter.setSpaceIndentation(spaceNum);
+ formatter.setIndentManuallySet(true);
+ }
+ }
+ else if ( IS_OPTION(arg, "indent=spaces") )
+ {
+ formatter.setSpaceIndentation(4);
+ // do NOT call setIndentManuallySet(true);
+ }
+ else if ( isParamOption(arg, "m", "min-conditional-indent=") )
+ {
+ int minIndent = 8;
+ string minIndentParam = GET_PARAMS(arg, "m", "min-conditional-indent=");
+ if (minIndentParam.length() > 0)
+ minIndent = atoi(minIndentParam.c_str());
+ if (minIndent > 40)
+ isOptionError(arg, errorInfo);
+ else
+ {
+ formatter.setMinConditionalIndentLength(minIndent);
+ formatter.setMinConditionalManuallySet(true);
+ }
+ }
+ else if ( isParamOption(arg, "M", "max-instatement-indent=") )
+ {
+ int maxIndent = 40;
+ string maxIndentParam = GET_PARAMS(arg, "M", "max-instatement-indent=");
+ if (maxIndentParam.length() > 0)
+ maxIndent = atoi(maxIndentParam.c_str());
+ if (maxIndent > 80)
+ isOptionError(arg, errorInfo);
+ else
+ formatter.setMaxInStatementIndentLength(maxIndent);
+ }
+ else if ( IS_OPTIONS(arg, "B", "indent-brackets") )
+ {
+ formatter.setBracketIndent(true);
+ }
+ else if ( IS_OPTIONS(arg, "G", "indent-blocks") )
+ {
+ formatter.setBlockIndent(true);
+ }
+ else if ( IS_OPTIONS(arg, "N", "indent-namespaces") )
+ {
+ formatter.setNamespaceIndent(true);
+ }
+ else if ( IS_OPTIONS(arg, "C", "indent-classes") )
+ {
+ formatter.setClassIndent(true);
+ }
+ else if ( IS_OPTIONS(arg, "S", "indent-switches") )
+ {
+ formatter.setSwitchIndent(true);
+ }
+ else if ( IS_OPTIONS(arg, "K", "indent-cases") )
+ {
+ formatter.setCaseIndent(true);
+ }
+ else if ( IS_OPTIONS(arg, "L", "indent-labels") )
+ {
+ formatter.setLabelIndent(true);
+ }
+ else if ( IS_OPTIONS(arg, "y", "break-closing-brackets") )
+ {
+ formatter.setBreakClosingHeaderBracketsMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "b", "brackets=break") )
+ {
+ formatter.setBracketFormatMode(BREAK_MODE);
+ }
+ else if ( IS_OPTIONS(arg, "a", "brackets=attach") )
+ {
+ formatter.setBracketFormatMode(ATTACH_MODE);
+ }
+ else if ( IS_OPTIONS(arg, "l", "brackets=linux") )
+ {
+ formatter.setBracketFormatMode(LINUX_MODE);
+ }
+ else if ( IS_OPTIONS(arg, "u", "brackets=stroustrup") )
+ {
+ formatter.setBracketFormatMode(STROUSTRUP_MODE);
+ }
+ else if ( IS_OPTIONS(arg, "g", "brackets=horstmann") )
+ {
+ formatter.setBracketFormatMode(HORSTMANN_MODE);
+ }
+ else if ( IS_OPTIONS(arg, "O", "keep-one-line-blocks") )
+ {
+ formatter.setBreakOneLineBlocksMode(false);
+ }
+ else if ( IS_OPTIONS(arg, "o", "keep-one-line-statements") )
+ {
+ formatter.setSingleStatementsMode(false);
+ }
+ else if ( IS_OPTIONS(arg, "P", "pad-paren") )
+ {
+ formatter.setParensOutsidePaddingMode(true);
+ formatter.setParensInsidePaddingMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "d", "pad-paren-out") )
+ {
+ formatter.setParensOutsidePaddingMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "D", "pad-paren-in") )
+ {
+ formatter.setParensInsidePaddingMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "H", "pad-header") )
+ {
+ formatter.setParensHeaderPaddingMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "U", "unpad-paren") )
+ {
+ formatter.setParensUnPaddingMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "p", "pad-oper") )
+ {
+ formatter.setOperatorPaddingMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "x", "delete-empty-lines") )
+ {
+ formatter.setDeleteEmptyLinesMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "E", "fill-empty-lines") )
+ {
+ formatter.setEmptyLineFill(true);
+ }
+ else if ( IS_OPTIONS(arg, "w", "indent-preprocessor") )
+ {
+ formatter.setPreprocessorIndent(true);
+ }
+ else if ( IS_OPTIONS(arg, "c", "convert-tabs") )
+ {
+ formatter.setTabSpaceConversionMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "F", "break-blocks=all") )
+ {
+ formatter.setBreakBlocksMode(true);
+ formatter.setBreakClosingHeaderBlocksMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "f", "break-blocks") )
+ {
+ formatter.setBreakBlocksMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "e", "break-elseifs") )
+ {
+ formatter.setBreakElseIfsMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "j", "add-brackets") )
+ {
+ formatter.setAddBracketsMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "J", "add-one-line-brackets") )
+ {
+ formatter.setAddOneLineBracketsMode(true);
+ }
+ else if ( IS_OPTIONS(arg, "Y", "indent-col1-comments") )
+ {
+ formatter.setIndentCol1CommentsMode(true);
+ }
+ else if ( IS_OPTION(arg, "align-pointer=type") )
+ {
+ formatter.setPointerAlignment(ALIGN_TYPE);
+ }
+ else if ( IS_OPTION(arg, "align-pointer=middle") )
+ {
+ formatter.setPointerAlignment(ALIGN_MIDDLE);
+ }
+ else if ( IS_OPTION(arg, "align-pointer=name") )
+ {
+ formatter.setPointerAlignment(ALIGN_NAME);
+ }
+ else if ( isParamOption(arg, "k") )
+ {
+ int align = 0;
+ string styleParam = GET_PARAM(arg, "k");
+ if (styleParam.length() > 0)
+ align = atoi(styleParam.c_str());
+ if (align < 1 || align > 3)
+ isOptionError(arg, errorInfo);
+ else if (align == 1)
+ formatter.setPointerAlignment(ALIGN_TYPE);
+ else if (align == 2)
+ formatter.setPointerAlignment(ALIGN_MIDDLE);
+ else if (align == 3)
+ formatter.setPointerAlignment(ALIGN_NAME);
+ }
+ // depreciated options /////////////////////////////////////////////////////////////////////////////////////
+ // depreciated in release 1.23
+ // removed from documentation in release 1.24
+ // may be removed at an appropriate time
+// else if ( IS_OPTION(arg, "style=kr") )
+// {
+// formatter.setFormattingStyle(STYLE_JAVA);
+// }
+ else if ( isParamOption(arg, "T", "force-indent=tab=") )
+ {
+ // the 'T' option will already have been processed
+ int spaceNum = 4;
+ string spaceNumParam = GET_PARAMS(arg, "T", "force-indent=tab=");
+ if (spaceNumParam.length() > 0)
+ spaceNum = atoi(spaceNumParam.c_str());
+ if (spaceNum < 1 || spaceNum > 20)
+ isOptionError(arg, errorInfo);
+ else
+ formatter.setTabIndentation(spaceNum, true);
+ }
+ else if ( IS_OPTION(arg, "brackets=break-closing") )
+ {
+ formatter.setBreakClosingHeaderBracketsMode(true);
+ }
+
+ else if ( IS_OPTION(arg, "one-line=keep-blocks") )
+ {
+ formatter.setBreakOneLineBlocksMode(false);
+ }
+ else if ( IS_OPTION(arg, "one-line=keep-statements") )
+ {
+ formatter.setSingleStatementsMode(false);
+ }
+ else if ( IS_OPTION(arg, "pad=paren") )
+ {
+ formatter.setParensOutsidePaddingMode(true);
+ formatter.setParensInsidePaddingMode(true);
+ }
+ else if ( IS_OPTION(arg, "pad=paren-out") )
+ {
+ formatter.setParensOutsidePaddingMode(true);
+ }
+ else if ( IS_OPTION(arg, "pad=paren-in") )
+ {
+ formatter.setParensInsidePaddingMode(true);
+ }
+ else if ( IS_OPTION(arg, "unpad=paren") )
+ {
+ formatter.setParensUnPaddingMode(true);
+ }
+ else if ( IS_OPTION(arg, "pad=oper") )
+ {
+ formatter.setOperatorPaddingMode(true);
+ }
+ // end depreciated options //////////////////////////////////////////////////////////////////////////////
+#ifdef ASTYLE_LIB
+ // End of options used by GUI
+ else
+ isOptionError(arg, errorInfo);
+#else
+ // Options used by only console
+ else if ( IS_OPTIONS(arg, "n", "suffix=none") )
+ {
+ g_console->setNoBackup(true);
+ }
+ else if ( isParamOption(arg, "suffix=") )
+ {
+ string suffixParam = GET_PARAM(arg, "suffix=");
+ if (suffixParam.length() > 0)
+ {
+ g_console->setOrigSuffix(suffixParam);
+ }
+ }
+ else if ( isParamOption(arg, "exclude=") )
+ {
+ string suffixParam = GET_PARAM(arg, "exclude=");
+ if (suffixParam.length() > 0)
+ g_console->updateExcludeVector(suffixParam);
+ }
+ else if ( IS_OPTIONS(arg, "r", "R") || IS_OPTION(arg, "recursive") )
+ {
+ g_console->setIsRecursive(true);
+ }
+ else if ( IS_OPTIONS(arg, "Z", "preserve-date") )
+ {
+ g_console->setPreserveDate(true);
+ }
+ else if ( IS_OPTIONS(arg, "v", "verbose") )
+ {
+ g_console->setIsVerbose(true);
+ }
+ else if ( IS_OPTIONS(arg, "Q", "formatted") )
+ {
+ g_console->setIsFormattedOnly(true);
+ }
+ else if ( IS_OPTIONS(arg, "q", "quiet") )
+ {
+ g_console->setIsQuiet(true);
+ }
+ else if ( IS_OPTIONS(arg, "X", "errors-to-stdout") )
+ {
+ _err = &cout;
+ }
+ else if ( IS_OPTION(arg, "lineend=windows") )
+ {
+ formatter.setLineEndFormat(LINEEND_WINDOWS);
+ }
+ else if ( IS_OPTION(arg, "lineend=linux") )
+ {
+ formatter.setLineEndFormat(LINEEND_LINUX);
+ }
+ else if ( IS_OPTION(arg, "lineend=macold") )
+ {
+ formatter.setLineEndFormat(LINEEND_MACOLD);
+ }
+ else if ( isParamOption(arg, "z") )
+ {
+ int lineendType = 0;
+ string lineendParam = GET_PARAM(arg, "z");
+ if (lineendParam.length() > 0)
+ lineendType = atoi(lineendParam.c_str());
+ if (lineendType < 1 || lineendType > 3)
+ isOptionError(arg, errorInfo);
+ else if (lineendType == 1)
+ formatter.setLineEndFormat(LINEEND_WINDOWS);
+ else if (lineendType == 2)
+ formatter.setLineEndFormat(LINEEND_LINUX);
+ else if (lineendType == 3)
+ formatter.setLineEndFormat(LINEEND_MACOLD);
+ }
+ else
+ {
+ (*_err) << errorInfo << arg << endl;
+ return false; // invalid option
+ }
+#endif
+// End of parseOption function
+ return true; //o.k.
+}
+
+//--------------------------------------------------------------------------------------
+// ASStreamIterator class
+// typename will be istringstream for GUI and istream otherwise
+//--------------------------------------------------------------------------------------
+
+template<typename T>
+ASStreamIterator<T>::ASStreamIterator(T *in)
+{
+ inStream = in;
+ buffer.reserve(200);
+ eolWindows = 0;
+ eolLinux = 0;
+ eolMacOld = 0;
+ outputEOL[0] = '\0';
+ peekStart = 0;
+ prevLineDeleted = false;
+ checkForEmptyLine = false;
+}
+
+template<typename T>
+ASStreamIterator<T>::~ASStreamIterator()
+{
+}
+
+/**
+ * read the input stream, delete any end of line characters,
+ * and build a string that contains the input line.
+ *
+ * @return string containing the next input line minus any end of line characters
+ */
+template<typename T>
+string ASStreamIterator<T>::nextLine(bool emptyLineWasDeleted)
+{
+ // verify that the current position is correct
+ assert (peekStart == 0);
+
+ // a deleted line may be replaced if break-blocks is requested
+ // this sets up the compare to check for a replaced empty line
+ if (prevLineDeleted)
+ {
+ prevLineDeleted = false;
+ checkForEmptyLine = true;
+ }
+ if (!emptyLineWasDeleted)
+ prevBuffer = buffer;
+ else
+ prevLineDeleted = true;
+
+ // read the next record
+ buffer.clear();
+ char ch;
+ inStream->get(ch);
+
+ while (!inStream->eof() && ch != '\n' && ch != '\r')
+ {
+ buffer.append(1, ch);
+ inStream->get(ch);
+ }
+
+ if (inStream->eof())
+ {
+ return buffer;
+ }
+
+ int peekCh = inStream->peek();
+
+ // find input end-of-line characters
+ if (!inStream->eof())
+ {
+ if (ch == '\r') // CR+LF is windows otherwise Mac OS 9
+ {
+ if (peekCh == '\n')
+ {
+ inStream->get();
+ eolWindows++;
+ }
+ else
+ eolMacOld++;
+ }
+ else // LF is Linux, allow for improbable LF/CR
+ {
+ if (peekCh == '\r')
+ {
+ inStream->get();
+ eolWindows++;
+ }
+ else
+ eolLinux++;
+ }
+ }
+ else
+ {
+ inStream->clear();
+ }
+
+ // set output end of line characters
+ if (eolWindows >= eolLinux)
+ {
+ if (eolWindows >= eolMacOld)
+ strcpy(outputEOL, "\r\n"); // Windows (CR+LF)
+ else
+ strcpy(outputEOL, "\r"); // MacOld (CR)
+ }
+ else if (eolLinux >= eolMacOld)
+ strcpy(outputEOL, "\n"); // Linux (LF)
+ else
+ strcpy(outputEOL, "\r"); // MacOld (CR)
+
+ return buffer;
+}
+
+// save the current position and get the next line
+// this can be called for multiple reads
+// when finished peeking you MUST call peekReset()
+// call this function from ASFormatter ONLY
+template<typename T>
+string ASStreamIterator<T>::peekNextLine()
+{
+ assert (hasMoreLines());
+ string nextLine;
+ char ch;
+
+ if (peekStart == 0)
+ peekStart = inStream->tellg();
+
+ // read the next record
+ inStream->get(ch);
+ while (!inStream->eof() && ch != '\n' && ch != '\r')
+ {
+ nextLine.append(1, ch);
+ inStream->get(ch);
+ }
+
+ if (inStream->eof())
+ {
+ return nextLine;
+ }
+
+ int peekCh = inStream->peek();
+
+ // remove end-of-line characters
+ if (!inStream->eof())
+ {
+ if ((peekCh == '\n' || peekCh == '\r') && peekCh != ch) ///////////// changed //////////
+ inStream->get();
+ }
+
+ return nextLine;
+}
+
+// reset current position and EOF for peekNextLine()
+template<typename T>
+void ASStreamIterator<T>::peekReset()
+{
+ assert(peekStart != 0);
+ inStream->clear();
+ inStream->seekg(peekStart);
+ peekStart = 0;
+}
+
+// save the last input line after input has reached EOF
+template<typename T>
+void ASStreamIterator<T>::saveLastInputLine()
+{
+ assert(inStream->eof());
+ prevBuffer = buffer;
+}
+
+// check for a change in line ends
+template<typename T>
+bool ASStreamIterator<T>::getLineEndChange(int lineEndFormat) const
+{
+ assert(lineEndFormat == LINEEND_DEFAULT
+ || lineEndFormat == LINEEND_WINDOWS
+ || lineEndFormat == LINEEND_LINUX
+ || lineEndFormat == LINEEND_MACOLD);
+
+ bool lineEndChange = false;
+ if (lineEndFormat == LINEEND_WINDOWS)
+ lineEndChange = (eolLinux + eolMacOld != 0);
+ else if (lineEndFormat == LINEEND_LINUX)
+ lineEndChange = (eolWindows + eolMacOld != 0);
+ else if (lineEndFormat == LINEEND_MACOLD)
+ lineEndChange = (eolWindows + eolLinux != 0);
+ else
+ {
+ if (eolWindows > 0)
+ lineEndChange = (eolLinux + eolMacOld != 0);
+ else if (eolLinux > 0)
+ lineEndChange = (eolWindows + eolMacOld != 0);
+ else if (eolMacOld > 0)
+ lineEndChange = (eolWindows + eolLinux != 0);
+ }
+ return lineEndChange;
+}
+
+#ifndef ASTYLE_LIB
+//--------------------------------------------------------------------------------------
+// ASConsole class
+// main function will be included only in the console build
+//--------------------------------------------------------------------------------------
+
+// rewrite a stringstream converting the line ends
+void ASConsole::convertLineEnds(ostringstream& out, int lineEnd)
+{
+ assert(lineEnd == LINEEND_WINDOWS || lineEnd == LINEEND_LINUX || lineEnd == LINEEND_MACOLD);
+ const string& inStr = out.str(); // avoids strange looking syntax
+ string outStr; // the converted ouput
+ int inLength = inStr.length();
+ for (int pos = 0; pos < inLength; pos++)
+ {
+ if (inStr[pos] == '\r')
+ {
+ if (inStr[pos+ 1] == '\n')
+ {
+ // CRLF
+ if (lineEnd == LINEEND_CR)
+ {
+ outStr += inStr[pos]; // Delete the LF
+ pos++;
+ continue;
+ }
+ else if (lineEnd == LINEEND_LF)
+ {
+ outStr += inStr[pos+1]; // Delete the CR
+ pos++;
+ continue;
+ }
+ else
+ {
+ outStr += inStr[pos]; // Do not change
+ outStr += inStr[pos+1];
+ pos++;
+ continue;
+ }
+ }
+ else
+ {
+ // CR
+ if (lineEnd == LINEEND_CRLF)
+ {
+ outStr += inStr[pos]; // Insert the CR
+ outStr += '\n'; // Insert the LF
+ continue;
+ }
+ else if (lineEnd == LINEEND_LF)
+ {
+ outStr += '\n'; // Insert the LF
+ continue;
+ }
+ else
+ {
+ outStr += inStr[pos]; // Do not change
+ continue;
+ }
+ }
+ }
+ else if (inStr[pos] == '\n')
+ {
+ // LF
+ if (lineEnd == LINEEND_CRLF)
+ {
+ outStr += '\r'; // Insert the CR
+ outStr += inStr[pos]; // Insert the LF
+ continue;
+ }
+ else if (lineEnd == LINEEND_CR)
+ {
+ outStr += '\r'; // Insert the CR
+ continue;
+ }
+ else
+ {
+ outStr += inStr[pos]; // Do not change
+ continue;
+ }
+ }
+ else
+ {
+ outStr += inStr[pos]; // Write the current char
+ }
+ }
+ // replace the stream
+ out.str(outStr);
+}
+
+void ASConsole::correctMixedLineEnds(ostringstream& out)
+{
+ LineEndFormat lineEndFormat = LINEEND_DEFAULT;
+ if (strcmp(outputEOL, "\r\n") == 0)
+ lineEndFormat = LINEEND_WINDOWS;
+ if (strcmp(outputEOL, "\n") == 0)
+ lineEndFormat = LINEEND_LINUX;
+ if (strcmp(outputEOL, "\r") == 0)
+ lineEndFormat = LINEEND_MACOLD;
+ convertLineEnds(out, lineEndFormat);
+}
+
+void ASConsole::error(const char *why, const char* what) const
+{
+ (*_err) << why << ' ' << what << '\n' << endl;
+ (*_err) << "Artistic Style has terminated!" << endl;
+ exit(EXIT_FAILURE);
+}
+
+/**
+ * If no files have been given, use cin for input and cout for output.
+ *
+ * This is used to format text for text editors like TextWrangler (Mac).
+ * Do NOT display any console messages when this function is used.
+ */
+void ASConsole::formatCinToCout(ASFormatter& formatter) const
+{
+ ASStreamIterator<istream> streamIterator(&cin); // create iterator for cin
+ formatter.init(&streamIterator);
+
+ while (formatter.hasMoreLines())
+ {
+ cout << formatter.nextLine();
+ if (formatter.hasMoreLines())
+ cout << streamIterator.getOutputEOL();
+ }
+ cout.flush();
+}
+
+/**
+ * Open input file, format it, and close the output.
+ *
+ * @param fileName The path and name of the file to be processed.
+ * @param formatter The formatter object.
+ */
+void ASConsole::formatFile(const string &fileName, ASFormatter &formatter)
+{
+ bool isFormatted = false;
+
+ // open input file
+ ifstream in(fileName.c_str(), ios::binary);
+ if (!in)
+ error("Could not open input file", fileName.c_str());
+
+ ostringstream out;
+
+ // Unless a specific language mode has been set, set the language mode
+ // according to the file's suffix.
+ if (!formatter.getModeManuallySet())
+ {
+ if (stringEndsWith(fileName, string(".java")))
+ formatter.setJavaStyle();
+ else if (stringEndsWith(fileName, string(".cs")))
+ formatter.setSharpStyle();
+ else
+ formatter.setCStyle();
+ }
+
+ ASStreamIterator<istream> streamIterator(&in);
+ formatter.init(&streamIterator);
+
+ // make sure encoding is 8 bit
+ // if not set the eofbit so the file is not formatted
+ FileEncoding encoding = getFileEncoding(in);
+ if (encoding != ENCODING_OK)
+ in.setstate(ios::eofbit);
+
+ // set line end format
+ string nextLine; // next output line
+ filesAreIdentical = true; // input and output files are identical
+ LineEndFormat lineEndFormat = formatter.getLineEndFormat();
+ initializeOutputEOL(lineEndFormat);
+
+ // format the file
+ while (formatter.hasMoreLines())
+ {
+ nextLine = formatter.nextLine();
+ out << nextLine;
+ linesOut++;
+ if (formatter.hasMoreLines())
+ {
+ setOutputEOL(lineEndFormat, streamIterator.getOutputEOL());
+ out << outputEOL;
+ }
+ else
+ streamIterator.saveLastInputLine(); // to compare the last input line
+
+ if (filesAreIdentical)
+ {
+ if (streamIterator.checkForEmptyLine)
+ {
+ if (nextLine.find_first_not_of(" \t") != string::npos)
+ filesAreIdentical = false;
+ }
+ else if (!streamIterator.compareToInputBuffer(nextLine))
+ filesAreIdentical = false;
+ streamIterator.checkForEmptyLine = false;
+ }
+ }
+ // correct for mixed line ends
+ if (lineEndsMixed)
+ {
+ correctMixedLineEnds(out);
+ filesAreIdentical = false;
+ }
+ in.close();
+
+ // if file has changed, write the new file
+ if (!filesAreIdentical || streamIterator.getLineEndChange(lineEndFormat))
+ {
+ writeOutputFile(fileName, out);
+ isFormatted = true;
+ filesFormatted++;
+ }
+ else
+ filesUnchanged++;
+
+ if (encoding != ENCODING_OK)
+ printBadEncoding(encoding);
+
+ // remove targetDirectory from filename if required by print
+ string displayName;
+ if (hasWildcard)
+ displayName = fileName.substr(targetDirectory.length() + 1);
+ else
+ displayName = fileName;
+
+ if (isFormatted)
+ printMsg("formatted " + displayName);
+ else
+ {
+ if (!isFormattedOnly || encoding != ENCODING_OK)
+ printMsg("unchanged* " + displayName);
+ }
+}
+
+// for unit testing
+vector<bool> ASConsole::getExcludeHitsVector()
+{
+ return excludeHitsVector;
+}
+
+// for unit testing
+vector<string> ASConsole::getExcludeVector()
+{ return excludeVector; }
+
+// for unit testing
+vector<string> ASConsole::getFileName()
+{ return fileName; }
+
+// for unit testing
+vector<string> ASConsole::getFileNameVector()
+{ return fileNameVector; }
+
+// for unit testing
+vector<string> ASConsole::getFileOptionsVector()
+{ return fileOptionsVector; }
+
+int ASConsole::getFilesUnchanged()
+{ return filesUnchanged; }
+
+int ASConsole::getFilesFormatted()
+{ return filesFormatted; }
+
+bool ASConsole::getIsFormattedOnly()
+{ return isFormattedOnly; }
+
+bool ASConsole::getIsQuiet()
+{ return isQuiet; }
+
+bool ASConsole::getIsRecursive()
+{ return isRecursive; }
+
+bool ASConsole::getIsVerbose()
+{ return isVerbose; }
+
+bool ASConsole::getLineEndsMixed()
+{ return lineEndsMixed; }
+
+bool ASConsole::getNoBackup()
+{ return noBackup; }
+
+string ASConsole::getOptionsFileName()
+{ return optionsFileName; }
+
+bool ASConsole::getOptionsFileRequired()
+{ return optionsFileRequired; }
+
+// for unit testing
+vector<string> ASConsole::getOptionsVector()
+{ return optionsVector; }
+
+string ASConsole::getOrigSuffix()
+{ return origSuffix; }
+
+bool ASConsole::getPreserveDate()
+{ return preserveDate; }
+
+// initialize output end of line
+void ASConsole::initializeOutputEOL(LineEndFormat lineEndFormat)
+{
+ assert(lineEndFormat == LINEEND_DEFAULT
+ || lineEndFormat == LINEEND_WINDOWS
+ || lineEndFormat == LINEEND_LINUX
+ || lineEndFormat == LINEEND_MACOLD);
+
+ outputEOL[0] = '\0'; // current line end
+ prevEOL[0] = '\0'; // previous line end
+ lineEndsMixed = false; // output has mixed line ends, LINEEND_DEFAULT only
+
+ if (lineEndFormat == LINEEND_WINDOWS)
+ strcpy(outputEOL, "\r\n");
+ else if (lineEndFormat == LINEEND_LINUX)
+ strcpy(outputEOL, "\n");
+ else if (lineEndFormat == LINEEND_MACOLD)
+ strcpy(outputEOL, "\r");
+ else
+ outputEOL[0] = '\0';
+}
+
+void ASConsole::printBadEncoding(FileEncoding encoding) const
+{
+ string msg = "********** following file unchanged: ";
+ if (encoding == UTF_16BE)
+ msg += "UTF-16BE encoding";
+ else if (encoding == UTF_16LE)
+ msg += "UTF-16LE encoding";
+ else if (encoding == UTF_32BE)
+ msg += "UTF-32BE encoding";
+ else if (encoding == UTF_32LE)
+ msg += "UTF-32LE encoding";
+ else
+ msg += "???????? encoding";
+ printMsg(msg);
+}
+
+void ASConsole::setIsFormattedOnly(bool state)
+{ isFormattedOnly = state; }
+
+void ASConsole::setIsQuiet(bool state)
+{ isQuiet = state; }
+
+void ASConsole::setIsRecursive(bool state)
+{ isRecursive = state; }
+
+void ASConsole::setIsVerbose(bool state)
+{ isVerbose = state; }
+
+void ASConsole::setNoBackup(bool state)
+{ noBackup = state; }
+
+void ASConsole::setOptionsFileName(string name)
+{ optionsFileName = name; }
+
+void ASConsole::setOptionsFileRequired(bool state)
+{ optionsFileRequired = state; }
+
+void ASConsole::setOrigSuffix(string suffix)
+{ origSuffix = suffix; }
+
+void ASConsole::setPreserveDate(bool state)
+{ preserveDate = state; }
+
+// set outputEOL variable
+void ASConsole::setOutputEOL(LineEndFormat lineEndFormat, const char* currentEOL)
+{
+ if (lineEndFormat == LINEEND_DEFAULT)
+ {
+ strcpy(outputEOL, currentEOL);
+ if (strlen(prevEOL) == 0)
+ strcpy(prevEOL, outputEOL);
+ if (strcmp(prevEOL, outputEOL) != 0)
+ {
+ lineEndsMixed = true;
+ filesAreIdentical = false;
+ strcpy(prevEOL, outputEOL);
+ }
+ }
+ else
+ {
+ strcpy(prevEOL, currentEOL);
+ if (strcmp(prevEOL, outputEOL) != 0)
+ filesAreIdentical = false;
+ }
+}
+
+#ifdef _WIN32 // Windows specific
+
+/**
+ * WINDOWS function to get the current directory.
+ * NOTE: getenv("CD") does not work for Windows Vista.
+ * The Windows function GetCurrentDirectory is used instead.
+ *
+ * @return The path of the current directory
+ */
+string ASConsole::getCurrentDirectory(const string &fileName) const
+{
+ char currdir[MAX_PATH];
+ currdir[0] = '\0';
+ if (!GetCurrentDirectory(sizeof(currdir), currdir))
+ error("Cannot find file", fileName.c_str());
+ return string(currdir);
+}
+
+/**
+ * WINDOWS function to resolve wildcards and recurse into sub directories.
+ * The fileName vector is filled with the path and names of files to process.
+ *
+ * @param directory The path of the directory to be processed.
+ * @param wildcard The wildcard to be processed (e.g. *.cpp).
+ * @param fileName An empty vector which will be filled with the path and names of files to process.
+ */
+void ASConsole::getFileNames(const string &directory, const string &wildcard)
+{
+ vector<string> subDirectory; // sub directories of directory
+ WIN32_FIND_DATA FindFileData; // for FindFirstFile and FindNextFile
+
+ // Find the first file in the directory
+ string firstFile = directory + "\\*";
+ HANDLE hFind = FindFirstFile(firstFile.c_str(), &FindFileData);
+
+ if (hFind == INVALID_HANDLE_VALUE)
+ error("Cannot open directory", directory.c_str());
+
+ // save files and sub directories
+ do
+ {
+ // skip hidden or read only
+ if (FindFileData.cFileName[0] == '.'
+ || (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+ || (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
+ continue;
+
+ // if a sub directory and recursive, save sub directory
+ if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && isRecursive)
+ {
+ string subDirectoryPath = directory + g_fileSeparator + FindFileData.cFileName;
+ if (isPathExclued(subDirectoryPath))
+ printMsg("exclude " + subDirectoryPath.substr(mainDirectoryLength));
+ else
+ subDirectory.push_back(subDirectoryPath);
+ continue;
+ }
+
+ // save the file name
+ string filePathName = directory + g_fileSeparator + FindFileData.cFileName;
+ // check exclude before wildcmp to avoid "unmatched exclude" error
+ bool isExcluded = isPathExclued(filePathName);
+ // save file name if wildcard match
+ if (wildcmp(wildcard.c_str(), FindFileData.cFileName))
+ {
+ if (isExcluded)
+ printMsg("exclude " + filePathName.substr(mainDirectoryLength));
+ else
+ fileName.push_back(filePathName);
+ }
+ }
+ while (FindNextFile(hFind, &FindFileData) != 0);
+
+ // check for processing error
+ FindClose(hFind);
+ DWORD dwError = GetLastError();
+ if (dwError != ERROR_NO_MORE_FILES)
+ error("Error processing directory", directory.c_str());
+
+ // recurse into sub directories
+ // if not doing recursive subDirectory is empty
+ for (unsigned i = 0; i < subDirectory.size(); i++)
+ {
+ getFileNames(subDirectory[i], wildcard);
+ }
+
+ return;
+}
+
+#else // not _WIN32
+
+/**
+ * LINUX function to get the current directory.
+ * This is done if the fileName does not contain a path.
+ * It is probably from an editor sending a single file.
+ *
+ * @param fileName The filename is used only for the error message.
+ * @return The path of the current directory
+ */
+string ASConsole::getCurrentDirectory(const string &fileName) const
+{
+ char *currdir = getenv("PWD");
+ if (currdir == NULL)
+ error("Cannot find file", fileName.c_str());
+ return string(currdir);
+}
+
+/**
+ * LINUX function to resolve wildcards and recurse into sub directories.
+ * The fileName vector is filled with the path and names of files to process.
+ *
+ * @param directory The path of the directory to be processed.
+ * @param wildcard The wildcard to be processed (e.g. *.cpp).
+ * @param fileName An empty vector which will be filled with the path and names of files to process.
+ */
+void ASConsole::getFileNames(const string &directory, const string &wildcard)
+{
+ struct dirent *entry; // entry from readdir()
+ struct stat statbuf; // entry from stat()
+ vector<string> subDirectory; // sub directories of this directory
+
+ // errno is defined in <errno.h> and is set for errors in opendir, readdir, or stat
+ errno = 0;
+
+ DIR *dp = opendir(directory.c_str());
+ if (dp == NULL)
+ error("Cannot open directory", directory.c_str());
+
+ // save the first fileName entry for this recursion
+ const unsigned firstEntry = fileName.size();
+
+ // save files and sub directories
+ while ((entry = readdir(dp)) != NULL)
+ {
+ // get file status
+ string entryFilepath = directory + g_fileSeparator + entry->d_name;
+ if (stat(entryFilepath.c_str(), &statbuf) != 0)
+ {
+ if (errno == EOVERFLOW) // file over 2 GB is OK
+ {
+ errno = 0;
+ continue;
+ }
+ perror("errno message");
+ error("Error getting file status in directory", directory.c_str());
+ }
+ // skip hidden or read only
+ if (entry->d_name[0] == '.' || !(statbuf.st_mode & S_IWUSR))
+ continue;
+ // if a sub directory and recursive, save sub directory
+ if (S_ISDIR(statbuf.st_mode) && isRecursive)
+ {
+ if (isPathExclued(entryFilepath))
+ printMsg("exclude " + entryFilepath.substr(mainDirectoryLength));
+ else
+ subDirectory.push_back(entryFilepath);
+ continue;
+ }
+
+ // if a file, save file name
+ if (S_ISREG(statbuf.st_mode))
+ {
+ // check exclude before wildcmp to avoid "unmatched exclude" error
+ bool isExcluded = isPathExclued(entryFilepath);
+ // save file name if wildcard match
+ if (wildcmp(wildcard.c_str(), entry->d_name))
+ {
+ if (isExcluded)
+ printMsg("exclude " + entryFilepath.substr(mainDirectoryLength));
+ else
+ fileName.push_back(entryFilepath);
+ }
+ }
+ }
+
+ if (closedir(dp) != 0)
+ {
+ perror("errno message");
+ error("Error reading directory", directory.c_str());
+ }
+
+ // sort the current entries for fileName
+ if (firstEntry < fileName.size())
+ sort(&fileName[firstEntry], &fileName[fileName.size()]);
+
+ // recurse into sub directories
+ // if not doing recursive, subDirectory is empty
+ if (subDirectory.size() > 1)
+ sort(subDirectory.begin(), subDirectory.end());
+ for (unsigned i = 0; i < subDirectory.size(); i++)
+ {
+ getFileNames(subDirectory[i], wildcard);
+ }
+
+ return;
+}
+
+#endif // _WIN32
+
+// check files for 16 or 32 bit encoding
+// the file must have a Byte Order Mark (BOM)
+// NOTE: some string functions don't work with NULLs (e.g. length())
+FileEncoding ASConsole::getFileEncoding(ifstream& in) const
+{
+ // BOM max is 4 bytes
+ char buff[4] = {'\0'};
+ in.read(buff, 4);
+ in.seekg(0);
+
+ FileEncoding encoding = ENCODING_OK;
+
+ if (memcmp(buff, "\x00\x00\xFE\xFF", 4) == 0)
+ encoding = UTF_32BE;
+ else if (memcmp(buff, "\xFF\xFE\x00\x00", 4) == 0)
+ encoding = UTF_32LE;
+ else if (memcmp(buff, "\xFE\xFF", 2) == 0)
+ encoding = UTF_16BE;
+ else if (memcmp(buff, "\xFF\xFE", 2) == 0)
+ encoding = UTF_16LE;
+
+ return encoding;
+}
+
+// get individual file names from the command-line file path
+void ASConsole::getFilePaths(string &filePath)
+{
+ fileName.clear();
+ targetDirectory = string();
+ targetFilename = string();
+
+ // separate directory and file name
+ size_t separator = filePath.find_last_of(g_fileSeparator);
+ if (separator == string::npos)
+ {
+ // if no directory is present, use the currently active directory
+ targetDirectory = getCurrentDirectory(filePath);
+ targetFilename = filePath;
+ mainDirectoryLength = targetDirectory.length() + 1; // +1 includes trailing separator
+ }
+ else
+ {
+ targetDirectory = filePath.substr(0, separator);
+ targetFilename = filePath.substr(separator+1);
+ mainDirectoryLength = targetDirectory.length() + 1; // +1 includes trailing separator
+ }
+
+ if (targetFilename.length() == 0)
+ error("Missing filename in", filePath.c_str());
+
+ // check filename for wildcards
+ hasWildcard = false;
+ if (targetFilename.find_first_of( "*?") != string::npos)
+ hasWildcard = true;
+
+ // clear exclude hits vector
+ for (size_t ix = 0; ix < excludeHitsVector.size(); ix++)
+ excludeHitsVector[ix] = false;
+
+ // display directory name for wildcard processing
+ if (hasWildcard)
+ {
+ printMsg("--------------------------------------------------");
+ printMsg("directory " + targetDirectory + g_fileSeparator + targetFilename);
+ }
+
+ // create a vector of paths and file names to process
+ if (hasWildcard || isRecursive)
+ getFileNames(targetDirectory, targetFilename);
+ else
+ fileName.push_back(targetDirectory + g_fileSeparator + targetFilename);
+
+ if (hasWildcard)
+ printMsg("--------------------------------------------------");
+
+ // check for unprocessed excludes
+ bool excludeErr = false;
+ for (size_t ix = 0; ix < excludeHitsVector.size(); ix++)
+ {
+ if (excludeHitsVector[ix] == false)
+ {
+ (*_err) << "Unmatched exclude " << excludeVector[ix].c_str() << endl;
+ excludeErr = true;
+ }
+ }
+#ifndef ASTYLECON_LIB
+ // abort if not a test
+ if (excludeErr)
+ exit(EXIT_FAILURE);
+#endif
+ // check if files were found (probably an input error if not)
+ if (fileName.size() == 0)
+ (*_err) << "No file to process " << filePath.c_str() << endl;
+}
+
+bool ASConsole::fileNameVectorIsEmpty()
+{
+ return fileNameVector.empty();
+}
+
+// compare a path to the exclude vector
+// used for both directories and filenames
+// updates the g_excludeHitsVector
+// return true if a match
+bool ASConsole::isPathExclued(const string &subPath)
+{
+ bool retVal = false;
+
+ // read the exclude vector checking for a match
+ for (size_t i = 0; i < excludeVector.size(); i++)
+ {
+ string exclude = excludeVector[i];
+
+ if (subPath.length() < exclude.length())
+ continue;
+
+ size_t compareStart = subPath.length() - exclude.length();
+ // subPath compare must start with a directory name
+ if (compareStart > 0)
+ {
+ char lastPathChar = subPath[compareStart - 1];
+ if (lastPathChar != g_fileSeparator)
+ continue;
+ }
+
+ string compare = subPath.substr(compareStart);
+ if (!g_isCaseSensitive)
+ {
+ // make it case insensitive for Windows
+ for (size_t j=0; j<compare.length(); j++)
+ compare[j] = (char)tolower(compare[j]);
+ for (size_t j=0; j<exclude.length(); j++)
+ exclude[j] = (char)tolower(exclude[j]);
+ }
+ // compare sub directory to exclude data - must check them all
+ if (compare == exclude)
+ {
+ excludeHitsVector[i] = true;
+ retVal = true;
+ break;
+ }
+ }
+ return retVal;
+}
+
+void ASConsole::printHelp() const
+{
+ (*_err) << endl;
+ (*_err) << " Artistic Style " << _version << endl;
+ (*_err) << " Maintained by: Jim Pattee\n";
+ (*_err) << " Original Author: Tal Davidson\n";
+ (*_err) << endl;
+ (*_err) << "Usage : astyle [options] Source1.cpp Source2.cpp [...]\n";
+ (*_err) << " astyle [options] < Original > Beautified\n";
+ (*_err) << endl;
+ (*_err) << "When indenting a specific file, the resulting indented file RETAINS the\n";
+ (*_err) << "original file-name. The original pre-indented file is renamed, with a\n";
+ (*_err) << "suffix of \".orig\" added to the original filename.\n";
+ (*_err) << endl;
+ (*_err) << "Wildcards (* and ?) may be used in the filename.\n";
+ (*_err) << "A \'recursive\' option can process directories recursively.\n";
+ (*_err) << endl;
+ (*_err) << "By default, astyle is set up to indent C/C++/C#/Java files, with four\n";
+ (*_err) << "spaces per indent, a maximal indentation of 40 spaces inside continuous\n";
+ (*_err) << "statements, a minimum indentation of eight spaces inside conditional\n";
+ (*_err) << "statements, and NO formatting options.\n";
+ (*_err) << endl;
+ (*_err) << "Option's Format:\n";
+ (*_err) << "----------------\n";
+ (*_err) << " Long options (starting with '--') must be written one at a time.\n";
+ (*_err) << " Short options (starting with '-') may be appended together.\n";
+ (*_err) << " Thus, -bps4 is the same as -b -p -s4.\n";
+ (*_err) << endl;
+ (*_err) << "Predefined Style Options:\n";
+ (*_err) << "-------------------------\n";
+ (*_err) << " --style=allman OR --style=ansi OR --style=bsd OR -A1\n";
+ (*_err) << " Allman style formatting/indenting.\n";
+ (*_err) << " Broken brackets.\n";
+ (*_err) << endl;
+ (*_err) << " --style=java OR -A2\n";
+ (*_err) << " Java style formatting/indenting.\n";
+ (*_err) << " Attached brackets.\n";
+ (*_err) << endl;
+ (*_err) << " --style=k&r OR --style=k/r OR -A3\n";
+ (*_err) << " Kernighan & Ritchie style formatting/indenting.\n";
+ (*_err) << " Linux brackets.\n";
+ (*_err) << endl;
+ (*_err) << " --style=stroustrup OR -A4\n";
+ (*_err) << " Stroustrup style formatting/indenting.\n";
+ (*_err) << " Stroustrup brackets.\n";
+ (*_err) << endl;
+ (*_err) << " --style=whitesmith OR -A5\n";
+ (*_err) << " Whitesmith style formatting/indenting.\n";
+ (*_err) << " Broken, indented brackets.\n";
+ (*_err) << " Indented class blocks and switch blocks.\n";
+ (*_err) << endl;
+ (*_err) << " --style=banner OR -A6\n";
+ (*_err) << " Banner style formatting/indenting.\n";
+ (*_err) << " Attached, indented brackets.\n";
+ (*_err) << " Indented class blocks and switch blocks.\n";
+ (*_err) << endl;
+ (*_err) << " --style=gnu OR -A7\n";
+ (*_err) << " GNU style formatting/indenting.\n";
+ (*_err) << " Broken brackets, indented blocks, indent is 2 spaces.\n";
+ (*_err) << endl;
+ (*_err) << " --style=linux OR -A8\n";
+ (*_err) << " GNU style formatting/indenting.\n";
+ (*_err) << " Linux brackets, indent is 8 spaces.\n";
+ (*_err) << endl;
+ (*_err) << " --style=horstmann OR -A9\n";
+ (*_err) << " Horstmann style formatting/indenting.\n";
+ (*_err) << " Horstmann brackets, indented switches, indent is 3 spaces.\n";
+ (*_err) << endl;
+ (*_err) << " --style=1tbs OR --style=otbs OR -A10\n";
+ (*_err) << " One True Brace Style formatting/indenting.\n";
+ (*_err) << " Linux brackets, add brackets to all conditionals.\n";
+ (*_err) << endl;
+ (*_err) << "Tab and Bracket Options:\n";
+ (*_err) << "------------------------\n";
+ (*_err) << " default indent option\n";
+ (*_err) << " If no indentation option is set,\n";
+ (*_err) << " the default option of 4 spaces will be used.\n";
+ (*_err) << endl;
+ (*_err) << " --indent=spaces=# OR -s#\n";
+ (*_err) << " Indent using # spaces per indent. Not specifying #\n";
+ (*_err) << " will result in a default of 4 spaces per indent.\n";
+ (*_err) << endl;
+ (*_err) << " --indent=tab OR --indent=tab=# OR -t OR -t#\n";
+ (*_err) << " Indent using tab characters, assuming that each\n";
+ (*_err) << " tab is # spaces long. Not specifying # will result\n";
+ (*_err) << " in a default assumption of 4 spaces per tab.\n";
+ (*_err) << endl;
+ (*_err) << " --indent=force-tab=# OR -T#\n";
+ (*_err) << " Indent using tab characters, assuming that each\n";
+ (*_err) << " tab is # spaces long. Force tabs to be used in areas\n";
+ (*_err) << " Astyle would prefer to use spaces.\n";
+ (*_err) << endl;
+ (*_err) << " default brackets option\n";
+ (*_err) << " If no brackets option is set,\n";
+ (*_err) << " the brackets will not be changed.\n";
+ (*_err) << endl;
+ (*_err) << " --brackets=break OR -b\n";
+ (*_err) << " Break brackets from pre-block code (i.e. ANSI C/C++ style).\n";
+ (*_err) << endl;
+ (*_err) << " --brackets=attach OR -a\n";
+ (*_err) << " Attach brackets to pre-block code (i.e. Java/K&R style).\n";
+ (*_err) << endl;
+ (*_err) << " --brackets=linux OR -l\n";
+ (*_err) << " Break definition-block brackets and attach command-block\n";
+ (*_err) << " brackets.\n";
+ (*_err) << endl;
+ (*_err) << " --brackets=stroustrup OR -u\n";
+ (*_err) << " Attach all brackets except function definition brackets.\n";
+ (*_err) << endl;
+ (*_err) << " --brackets=horstmann OR -g\n";
+ (*_err) << " Break brackets from pre-block code, but allow following\n";
+ (*_err) << " run-in statements on the same line as an opening bracket.\n";
+ (*_err) << endl;
+ (*_err) << "Indentation options:\n";
+ (*_err) << "--------------------\n";
+ (*_err) << " --indent-classes OR -C\n";
+ (*_err) << " Indent 'class' blocks, so that the inner 'public:',\n";
+ (*_err) << " 'protected:' and 'private: headers are indented in\n";
+ (*_err) << " relation to the class block.\n";
+ (*_err) << endl;
+ (*_err) << " --indent-switches OR -S\n";
+ (*_err) << " Indent 'switch' blocks, so that the inner 'case XXX:'\n";
+ (*_err) << " headers are indented in relation to the switch block.\n";
+ (*_err) << endl;
+ (*_err) << " --indent-cases OR -K\n";
+ (*_err) << " Indent case blocks from the 'case XXX:' headers.\n";
+ (*_err) << " Case statements not enclosed in blocks are NOT indented.\n";
+ (*_err) << endl;
+ (*_err) << " --indent-brackets OR -B\n";
+ (*_err) << " Add extra indentation to '{' and '}' block brackets.\n";
+ (*_err) << endl;
+ (*_err) << " --indent-blocks OR -G\n";
+ (*_err) << " Add extra indentation entire blocks (including brackets).\n";
+ (*_err) << endl;
+ (*_err) << " --indent-namespaces OR -N\n";
+ (*_err) << " Indent the contents of namespace blocks.\n";
+ (*_err) << endl;
+ (*_err) << " --indent-labels OR -L\n";
+ (*_err) << " Indent labels so that they appear one indent less than\n";
+ (*_err) << " the current indentation level, rather than being\n";
+ (*_err) << " flushed completely to the left (which is the default).\n";
+ (*_err) << endl;
+ (*_err) << " --indent-preprocessor OR -w\n";
+ (*_err) << " Indent multi-line #define statements.\n";
+ (*_err) << endl;
+ (*_err) << " --indent-col1-comments OR -Y\n";
+ (*_err) << " Indent line comments that start in column one.\n";
+ (*_err) << endl;
+ (*_err) << " --max-instatement-indent=# OR -M#\n";
+ (*_err) << " Indent a maximal # spaces in a continuous statement,\n";
+ (*_err) << " relative to the previous line.\n";
+ (*_err) << endl;
+ (*_err) << " --min-conditional-indent=# OR -m#\n";
+ (*_err) << " Indent a minimal # spaces in a continuous conditional\n";
+ (*_err) << " belonging to a conditional header.\n";
+ (*_err) << endl;
+ (*_err) << "Padding options:\n";
+ (*_err) << "--------------------\n";
+ (*_err) << " --break-blocks OR -f\n";
+ (*_err) << " Insert empty lines around unrelated blocks, labels, classes, ...\n";
+ (*_err) << endl;
+ (*_err) << " --break-blocks=all OR -F\n";
+ (*_err) << " Like --break-blocks, except also insert empty lines \n";
+ (*_err) << " around closing headers (e.g. 'else', 'catch', ...).\n";
+ (*_err) << endl;
+ (*_err) << " --pad-oper OR -p\n";
+ (*_err) << " Insert space paddings around operators.\n";
+ (*_err) << endl;
+ (*_err) << " --pad-paren OR -P\n";
+ (*_err) << " Insert space padding around parenthesis on both the outside\n";
+ (*_err) << " and the inside.\n";
+ (*_err) << endl;
+ (*_err) << " --pad-paren-out OR -d\n";
+ (*_err) << " Insert space padding around parenthesis on the outside only.\n";
+ (*_err) << endl;
+ (*_err) << " --pad-paren-in OR -D\n";
+ (*_err) << " Insert space padding around parenthesis on the inside only.\n";
+ (*_err) << endl;
+ (*_err) << " --pad-header OR -H\n";
+ (*_err) << " Insert space padding after paren headers (e.g. 'if', 'for'...).\n";
+ (*_err) << endl;
+ (*_err) << " --unpad-paren OR -U\n";
+ (*_err) << " Remove unnecessary space padding around parenthesis. This\n";
+ (*_err) << " can be used in combination with the 'pad' options above.\n";
+ (*_err) << endl;
+ (*_err) << " --delete-empty-lines OR -x\n";
+ (*_err) << " Delete empty lines within a function or method.\n";
+ (*_err) << " It will NOT delete lines added by the break-blocks options.\n";
+ (*_err) << endl;
+ (*_err) << " --fill-empty-lines OR -E\n";
+ (*_err) << " Fill empty lines with the white space of their\n";
+ (*_err) << " previous lines.\n";
+ (*_err) << endl;
+ (*_err) << "Formatting options:\n";
+ (*_err) << "-------------------\n";
+ (*_err) << " --break-closing-brackets OR -y\n";
+ (*_err) << " Break brackets before closing headers (e.g. 'else', 'catch', ...).\n";
+ (*_err) << " Use with --brackets=attach, --brackets=linux, \n";
+ (*_err) << " or --brackets=stroustrup.\n";
+ (*_err) << endl;
+ (*_err) << " --break-elseifs OR -e\n";
+ (*_err) << " Break 'else if()' statements into two different lines.\n";
+ (*_err) << endl;
+ (*_err) << " --add-brackets OR -j\n";
+ (*_err) << " Add brackets to unbracketed one line conditional statements.\n";
+ (*_err) << endl;
+ (*_err) << " --add-one-line-brackets OR -J\n";
+ (*_err) << " Add one line brackets to unbracketed one line conditional\n";
+ (*_err) << " statements.\n";
+ (*_err) << endl;
+ (*_err) << " --keep-one-line-blocks OR -O\n";
+ (*_err) << " Don't break blocks residing completely on one line.\n";
+ (*_err) << endl;
+ (*_err) << " --keep-one-line-statements OR -o\n";
+ (*_err) << " Don't break lines containing multiple statements into\n";
+ (*_err) << " multiple single-statement lines.\n";
+ (*_err) << endl;
+ (*_err) << " --convert-tabs OR -c\n";
+ (*_err) << " Convert tabs to the appropriate number of spaces.\n";
+ (*_err) << endl;
+ (*_err) << " --align-pointer=type OR -k1\n";
+ (*_err) << " --align-pointer=middle OR -k2\n";
+ (*_err) << " --align-pointer=name OR -k3\n";
+ (*_err) << " Attach a pointer or reference operator (* or &) to either\n";
+ (*_err) << " the operator type (left), middle, or operator name (right).\n";
+ (*_err) << endl;
+ (*_err) << " --mode=c\n";
+ (*_err) << " Indent a C or C++ source file (this is the default).\n";
+ (*_err) << endl;
+ (*_err) << " --mode=java\n";
+ (*_err) << " Indent a Java source file.\n";
+ (*_err) << endl;
+ (*_err) << " --mode=cs\n";
+ (*_err) << " Indent a C# source file.\n";
+ (*_err) << endl;
+ (*_err) << "Other options:\n";
+ (*_err) << "--------------\n";
+ (*_err) << " --suffix=####\n";
+ (*_err) << " Append the suffix #### instead of '.orig' to original filename.\n";
+ (*_err) << endl;
+ (*_err) << " --suffix=none OR -n\n";
+ (*_err) << " Do not retain a backup of the original file.\n";
+ (*_err) << endl;
+ (*_err) << " --options=####\n";
+ (*_err) << " Specify an options file #### to read and use.\n";
+ (*_err) << endl;
+ (*_err) << " --options=none\n";
+ (*_err) << " Disable the default options file.\n";
+ (*_err) << " Only the command-line parameters will be used.\n";
+ (*_err) << endl;
+ (*_err) << " --recursive OR -r OR -R\n";
+ (*_err) << " Process subdirectories recursively.\n";
+ (*_err) << endl;
+ (*_err) << " --exclude=####\n";
+ (*_err) << " Specify a file or directory #### to be excluded from processing.\n";
+ (*_err) << endl;
+ (*_err) << " --errors-to-stdout OR -X\n";
+ (*_err) << " Print errors and help information to standard-output rather than\n";
+ (*_err) << " to standard-error.\n";
+ (*_err) << endl;
+ (*_err) << " --preserve-date OR -Z\n";
+ (*_err) << " The date and time modified will not be changed in the formatted file.\n";
+ (*_err) << endl;
+ (*_err) << " --verbose OR -v\n";
+ (*_err) << " Verbose mode. Extra informational messages will be displayed.\n";
+ (*_err) << endl;
+ (*_err) << " --formatted OR -Q\n";
+ (*_err) << " Formatted display mode. Display only the files that have been formatted.\n";
+ (*_err) << endl;
+ (*_err) << " --quiet OR -q\n";
+ (*_err) << " Quiet mode. Suppress all output except error messages.\n";
+ (*_err) << endl;
+ (*_err) << " --lineend=windows OR -z1\n";
+ (*_err) << " --lineend=linux OR -z2\n";
+ (*_err) << " --lineend=macold OR -z3\n";
+ (*_err) << " Force use of the specified line end style. Valid options\n";
+ (*_err) << " are windows (CRLF), linux (LF), and macold (CR).\n";
+ (*_err) << endl;
+ (*_err) << " --version OR -V\n";
+ (*_err) << " Print version number.\n";
+ (*_err) << endl;
+ (*_err) << " --help OR -h OR -?\n";
+ (*_err) << " Print this help message.\n";
+ (*_err) << endl;
+ (*_err) << "Default options file:\n";
+ (*_err) << "---------------------\n";
+ (*_err) << " Artistic Style looks for a default options file in the\n";
+ (*_err) << " following order:\n";
+ (*_err) << " 1. The contents of the ARTISTIC_STYLE_OPTIONS environment\n";
+ (*_err) << " variable if it exists.\n";
+ (*_err) << " 2. The file called .astylerc in the directory pointed to by the\n";
+ (*_err) << " HOME environment variable ( i.e. $HOME/.astylerc ).\n";
+ (*_err) << " 3. The file called astylerc in the directory pointed to by the\n";
+ (*_err) << " USERPROFILE environment variable ( i.e. %USERPROFILE%\\astylerc ).\n";
+ (*_err) << " If a default options file is found, the options in this file\n";
+ (*_err) << " will be parsed BEFORE the command-line options.\n";
+ (*_err) << " Long options within the default option file may be written without\n";
+ (*_err) << " the preliminary '--'.\n";
+ (*_err) << endl;
+}
+
+
+/**
+ * Process files in the fileNameVector.
+ *
+ * @param formatter The formatter object.
+ */
+void ASConsole::processFiles(ASFormatter &formatter)
+{
+ if (isVerbose)
+ printVerboseHeader();
+
+ clock_t startTime = clock(); // start time of file formatting
+
+ // loop thru input fileNameVector and process the files
+ for (size_t i = 0; i < fileNameVector.size(); i++)
+ {
+ getFilePaths(fileNameVector[i]);
+
+ // loop thru fileName vector formatting the files
+ for (size_t j = 0; j < fileName.size(); j++)
+ formatFile(fileName[j], formatter);
+ }
+
+ // files are processed, display stats
+ if (isVerbose)
+ printVerboseStats(startTime);
+
+}
+
+// process options from the command line and options file
+// build the vectors fileNameVector, excludeVector, optionsVector, and fileOptionsVector
+processReturn ASConsole::processOptions(int argc, char** argv, ASFormatter &formatter)
+{
+ string arg;
+ bool ok = true;
+ bool shouldParseOptionsFile = true;
+
+ // get command line options
+ for (int i = 1; i < argc; i++)
+ {
+ arg = string(argv[i]);
+
+ if ( IS_OPTION(arg, "--options=none") )
+ {
+ shouldParseOptionsFile = false;
+ }
+ else if ( isParamOption(arg, "--options=") )
+ {
+ optionsFileName = GET_PARAM(arg, "--options=");
+ optionsFileRequired = true;
+ if (optionsFileName.compare("") == 0)
+ setOptionsFileName(" ");
+ }
+ else if ( IS_OPTION(arg, "-h")
+ || IS_OPTION(arg, "--help")
+ || IS_OPTION(arg, "-?") )
+ {
+ printHelp();
+ return(END_SUCCESS);
+ }
+ else if ( IS_OPTION(arg, "-V" )
+ || IS_OPTION(arg, "--version") )
+ {
+ (*_err) << "Artistic Style Version " << _version << endl;
+ return(END_SUCCESS);
+ }
+ else if (arg[0] == '-')
+ {
+ optionsVector.push_back(arg);
+ }
+ else // file-name
+ {
+ standardizePath(arg);
+ fileNameVector.push_back(arg);
+ }
+ }
+
+ // get options file path and name
+ if (shouldParseOptionsFile)
+ {
+ if (optionsFileName.compare("") == 0)
+ {
+ char* env = getenv("ARTISTIC_STYLE_OPTIONS");
+ if (env != NULL)
+ setOptionsFileName(env);
+ }
+ if (optionsFileName.compare("") == 0)
+ {
+ char* env = getenv("HOME");
+ if (env != NULL)
+ setOptionsFileName(string(env) + "/.astylerc");
+ }
+ if (optionsFileName.compare("") == 0)
+ {
+ char* env = getenv("USERPROFILE");
+ if (env != NULL)
+ setOptionsFileName(string(env) + "/astylerc");
+ }
+ if (optionsFileName.compare("") != 0)
+ standardizePath(optionsFileName);
+ }
+
+ // create the options file vector and parse the options for errors
+ if (optionsFileName.compare("") != 0)
+ {
+ ifstream optionsIn(optionsFileName.c_str());
+ if (optionsIn)
+ {
+ importOptions(optionsIn, fileOptionsVector);
+ ok = parseOptions(formatter,
+ fileOptionsVector.begin(),
+ fileOptionsVector.end(),
+ string("Invalid option in default options file: "));
+ }
+ else
+ {
+ if (optionsFileRequired)
+ {
+ (*_err) << "Could not open options file: " << optionsFileName.c_str() << endl;
+ return (END_FAILURE);
+ }
+ optionsFileName.clear();
+ }
+ optionsIn.close();
+ }
+ if (!ok)
+ {
+ (*_err) << "For help on options, type 'astyle -h' " << endl;
+ return(END_FAILURE);
+ }
+
+ // parse the command line options vector for errors
+ ok = parseOptions(formatter,
+ optionsVector.begin(),
+ optionsVector.end(),
+ string("Invalid command line option: "));
+ if (!ok)
+ {
+ (*_err) << "For help on options, type 'astyle -h' \n" << endl;
+ return(END_FAILURE);
+ }
+ return(CONTINUE);
+}
+
+// remove a file and check for an error
+void ASConsole::removeFile(const char* fileName, const char* errMsg) const
+{
+ remove(fileName);
+ if (errno == ENOENT) // no file is OK
+ errno = 0;
+ if (errno)
+ {
+ perror("errno message");
+ error(errMsg, fileName);
+ }
+}
+
+// rename a file and check for an error
+void ASConsole::renameFile(const char* oldFileName, const char* newFileName, const char* errMsg) const
+{
+ rename(oldFileName, newFileName);
+ // if file still exists the remove needs more time - retry
+ if (errno == EEXIST)
+ {
+ errno = 0;
+ waitForRemove(newFileName);
+ rename(oldFileName, newFileName);
+ }
+ if (errno)
+ {
+ perror("errno message");
+ error(errMsg, oldFileName);
+ }
+}
+
+// make sure file separators are correct type (Windows or Linux)
+// remove ending file separator
+// remove beginning file separator if requested and NOT a complete file path
+void ASConsole::standardizePath(string &path, bool removeBeginningSeparator /*false*/) const
+{
+#ifdef __VMS
+ struct FAB fab;
+ struct NAML naml;
+ char less[NAML$C_MAXRSS];
+ char sess[NAM$C_MAXRSS];
+ int r0_status;
+
+ // If we are on a VMS system, translate VMS style filenames to unix
+ // style.
+ fab = cc$rms_fab;
+ fab.fab$l_fna = (char *)-1;
+ fab.fab$b_fns = 0;
+ fab.fab$l_naml = &naml;
+ naml = cc$rms_naml;
+ strcpy (sess, path.c_str());
+ naml.naml$l_long_filename = (char *)sess;
+ naml.naml$l_long_filename_size = path.length();
+ naml.naml$l_long_expand = less;
+ naml.naml$l_long_expand_alloc = sizeof (less);
+ naml.naml$l_esa = sess;
+ naml.naml$b_ess = sizeof (sess);
+ naml.naml$v_no_short_upcase = 1;
+ r0_status = sys$parse (&fab);
+ if (r0_status == RMS$_SYN)
+ {
+ error("File syntax error", path.c_str());
+ }
+ else
+ {
+ if (!$VMS_STATUS_SUCCESS(r0_status))
+ {
+ (void)lib$signal (r0_status);
+ }
+ }
+ less[naml.naml$l_long_expand_size - naml.naml$b_ver] = '\0';
+ sess[naml.naml$b_esl - naml.naml$b_ver] = '\0';
+ if (naml.naml$l_long_expand_size > naml.naml$b_esl)
+ {
+ path = decc$translate_vms (less);
+ }
+ else
+ {
+ path = decc$translate_vms (sess);
+ }
+#endif /* __VMS */
+
+ // make sure separators are correct type (Windows or Linux)
+ for (size_t i = 0; i < path.length(); i++)
+ {
+ i = path.find_first_of("/\\", i);
+ if (i == string::npos)
+ break;
+ path[i] = g_fileSeparator;
+ }
+ // remove separator from the end
+ if (path[path.length()-1] == g_fileSeparator)
+ path.erase(path.length()-1, 1);
+ // remove beginning separator if requested
+ if (removeBeginningSeparator && (path[0] == g_fileSeparator))
+ path.erase(0, 1);
+}
+
+void ASConsole::printMsg(const string &msg) const
+{
+ if (isQuiet)
+ return;
+ cout << msg << endl;
+}
+
+void ASConsole::printVerboseHeader() const
+{
+ assert(isVerbose);
+ if (isQuiet)
+ return;
+ cout << "Artistic Style " << _version << endl;
+ if (optionsFileName.compare("") != 0)
+ cout << "Using default options file " << optionsFileName << endl;
+}
+
+void ASConsole::printVerboseStats(clock_t startTime) const
+{
+ assert(isVerbose);
+ if (isQuiet)
+ return;
+ if (hasWildcard)
+ cout << "--------------------------------------------------" << endl;
+ cout << filesFormatted << " formatted, ";
+ cout << filesUnchanged << " unchanged, ";
+
+ // show processing time
+ clock_t stopTime = clock();
+ float secs = float ((stopTime - startTime) / CLOCKS_PER_SEC);
+ if (secs < 60)
+ {
+ // show tenths of a second if time is less than 20 seconds
+ cout.precision(2);
+ if (secs >= 10 && secs < 20)
+ cout.precision(3);
+ cout << secs << " seconds, ";
+ cout.precision(0);
+ }
+ else
+ {
+ // show minutes and seconds if time is greater than one minute
+ int min = (int) secs / 60;
+ secs -= min * 60;
+ int minsec = int (secs + .5);
+ cout << min << " min " << minsec << " sec, ";
+ }
+
+ cout << linesOut << " lines" << endl;
+}
+
+bool ASConsole::stringEndsWith(const string &str, const string &suffix) const
+{
+ int strIndex = (int) str.length() - 1;
+ int suffixIndex = (int) suffix.length() - 1;
+
+ while (strIndex >= 0 && suffixIndex >= 0)
+ {
+ if (tolower(str[strIndex]) != tolower(suffix[suffixIndex]))
+ return false;
+
+ --strIndex;
+ --suffixIndex;
+ }
+ // suffix longer than string
+ if (strIndex < 0 && suffixIndex >= 0)
+ return false;
+ return true;
+}
+
+void ASConsole::updateExcludeVector(string suffixParam)
+{
+ excludeVector.push_back(suffixParam);
+ standardizePath(excludeVector.back(), true);
+ excludeHitsVector.push_back(false);
+}
+
+void ASConsole::sleep(int seconds) const
+{
+ clock_t endwait;
+ endwait = clock_t (clock () + seconds * CLOCKS_PER_SEC);
+ while (clock() < endwait) {}
+}
+
+int ASConsole::waitForRemove(const char* newFileName) const
+{
+ struct stat stBuf;
+ int seconds;
+ // sleep a max of 20 seconds for the remove
+ for (seconds = 0; seconds < 20; seconds++)
+ {
+ sleep(1);
+ if (stat(newFileName, &stBuf) != 0)
+ break;
+ }
+ errno = 0;
+ return seconds;
+}
+
+// From The Code Project http://www.codeproject.com/string/wildcmp.asp
+// Written by Jack Handy - jakkhandy@hotmail.com
+// Modified to compare case insensitive for Windows
+int ASConsole::wildcmp(const char *wild, const char *data) const
+{
+ const char *cp = NULL, *mp = NULL;
+ bool cmpval;
+
+ while ((*data) && (*wild != '*'))
+ {
+ if (!g_isCaseSensitive)
+ cmpval = (tolower(*wild) != tolower(*data)) && (*wild != '?');
+ else
+ cmpval = (*wild != *data) && (*wild != '?');
+
+ if (cmpval)
+ {
+ return 0;
+ }
+ wild++;
+ data++;
+ }
+
+ while (*data)
+ {
+ if (*wild == '*')
+ {
+ if (!*++wild)
+ {
+ return 1;
+ }
+ mp = wild;
+ cp = data+1;
+ }
+ else
+ {
+ if (!g_isCaseSensitive)
+ cmpval = (tolower(*wild) == tolower(*data) || (*wild == '?'));
+ else
+ cmpval = (*wild == *data) || (*wild == '?');
+
+ if (cmpval)
+ {
+ wild++;
+ data++;
+ }
+ else
+ {
+ wild = mp;
+ data = cp++;
+ }
+ }
+ }
+
+ while (*wild == '*')
+ {
+ wild++;
+ }
+ return !*wild;
+}
+
+void ASConsole::writeOutputFile(const string &fileName, ostringstream &out) const
+{
+ // save date accessed and date modified of original file
+ struct stat stBuf;
+ bool statErr = false;
+ if (stat(fileName.c_str(), &stBuf) == -1)
+ statErr = true;
+
+ // create a backup
+ if (!noBackup)
+ {
+ string origFileName = fileName + origSuffix;
+ removeFile(origFileName.c_str(), "Could not remove pre-existing backup file");
+ renameFile(fileName.c_str(), origFileName.c_str(), "Could not create backup file");
+ }
+
+ // write the output file
+ ofstream fout(fileName.c_str(), ios::binary | ios::trunc);
+ if (!fout)
+ error("Could not open output file", fileName.c_str());
+ fout << out.str();
+ fout.close();
+
+ // change date modified to original file date
+ if (preserveDate)
+ {
+ if (!statErr)
+ {
+ struct utimbuf outBuf;
+ outBuf.actime = stBuf.st_atime;
+ // add ticks so 'make' will recoginze a change
+ // Visual Studio 2008 needs more than 1
+ outBuf.modtime = stBuf.st_mtime + 10;
+ if (utime(fileName.c_str(), &outBuf) == -1)
+ statErr = true;
+ }
+ if (statErr)
+ (*_err) << "********* could not preserve following file date" << endl;
+ }
+}
+
+#endif
+// ******************* end of console functions ***********************************************
+
+} // end of namespace astyle
+
+// ******************* end of astyle namespace ***********************************************
+
+using namespace astyle;
+
+#ifdef ASTYLE_JNI
+// ************************* JNI functions *****************************************************
+// called by a java program to get the version number
+// the function name is constructed from method names in the calling java program
+extern "C" EXPORT
+jstring STDCALL Java_AStyleInterface_AStyleGetVersion(JNIEnv* env, jclass)
+{
+ return env->NewStringUTF(_version);
+}
+
+// called by a java program to format the source code
+// the function name is constructed from method names in the calling java program
+extern "C" EXPORT
+jstring STDCALL Java_AStyleInterface_AStyleMain(JNIEnv* env,
+ jobject obj,
+ jstring textInJava,
+ jstring optionsJava)
+{
+ g_env = env; // make object available globally
+ g_obj = obj; // make object available globally
+
+ jstring textErr = env->NewStringUTF(""); // zero length text returned if an error occurs
+
+ // get the method ID
+ jclass cls = env->GetObjectClass(obj);
+ g_mid = env->GetMethodID(cls, "ErrorHandler","(ILjava/lang/String;)V");
+ if (g_mid == 0)
+ {
+ cout << "Cannot find java method ErrorHandler" << endl;
+ return textErr;
+ }
+
+ // convert jstring to char*
+ const char* textIn = env->GetStringUTFChars(textInJava, NULL);
+ const char* options = env->GetStringUTFChars(optionsJava, NULL);
+
+ // call the C++ formatting function
+ char* textOut = AStyleMain(textIn, options, javaErrorHandler, javaMemoryAlloc);
+ // if an error message occurred it was displayed by errorHandler
+ if (textOut == NULL)
+ return textErr;
+
+ // release memory
+ jstring textOutJava = env->NewStringUTF(textOut);
+ delete [] textOut;
+ env->ReleaseStringUTFChars(textInJava, textIn);
+ env->ReleaseStringUTFChars(optionsJava, options);
+
+ return textOutJava;
+}
+
+// Call the Java error handler
+void STDCALL javaErrorHandler(int errorNumber, char* errorMessage)
+{
+ jstring errorMessageJava = g_env->NewStringUTF(errorMessage);
+ g_env->CallVoidMethod(g_obj, g_mid, errorNumber, errorMessageJava);
+}
+
+// Allocate memory for the formatted text
+char* STDCALL javaMemoryAlloc(unsigned long memoryNeeded)
+{
+ // error condition is checked after return from AStyleMain
+ char* buffer = new(nothrow) char [memoryNeeded];
+ return buffer;
+}
+#endif
+
+#ifdef ASTYLE_LIB
+// ************************* GUI functions ****************************************************
+/*
+ * IMPORTANT VC DLL linker must have the parameter /EXPORT:AStyleMain=_AStyleMain@16
+ * /EXPORT:AStyleGetVersion=_AStyleGetVersion@0
+ */
+extern "C" EXPORT char* STDCALL
+AStyleMain(const char* pSourceIn, // pointer to the source to be formatted
+ const char* pOptions, // pointer to AStyle options, separated by \n
+ fpError fpErrorHandler, // pointer to error handler function
+ fpAlloc fpMemoryAlloc) // pointer to memory allocation function
+{
+ if (fpErrorHandler == NULL) // cannot display a message if no error handler
+ return NULL;
+
+ if (pSourceIn == NULL)
+ {
+ fpErrorHandler(101, (char*)"No pointer to source input.");
+ return NULL;
+ }
+ if (pOptions == NULL)
+ {
+ fpErrorHandler(102, (char*)"No pointer to AStyle options.");
+ return NULL;
+ }
+ if (fpMemoryAlloc == NULL)
+ {
+ fpErrorHandler(103, (char*)"No pointer to memory allocation function.");
+ return NULL;
+ }
+
+ ASFormatter formatter;
+
+ vector<string> optionsVector;
+ istringstream opt(pOptions);
+ _err = new stringstream;
+
+ importOptions(opt, optionsVector);
+
+ parseOptions(formatter,
+ optionsVector.begin(),
+ optionsVector.end(),
+ "Invalid Artistic Style options.\n"
+ "The following options were not processed:");
+
+ if (_err->str().length() > 0)
+ fpErrorHandler(210, (char*) _err->str().c_str());
+
+ delete _err;
+ _err = NULL;
+
+ istringstream in(pSourceIn);
+ ASStreamIterator<istringstream> streamIterator(&in);
+ ostringstream out;
+ formatter.init(&streamIterator);
+
+ while (formatter.hasMoreLines())
+ {
+ out << formatter.nextLine();
+ if (formatter.hasMoreLines())
+ out << streamIterator.getOutputEOL();
+ }
+
+ unsigned long textSizeOut = out.str().length();
+ char* pTextOut = fpMemoryAlloc(textSizeOut + 1); // call memory allocation function
+// pTextOut = NULL; // for testing
+ if (pTextOut == NULL)
+ {
+ fpErrorHandler(110, (char*)"Allocation failure on output.");
+ return NULL;
+ }
+
+ strcpy(pTextOut, out.str().c_str());
+
+ return pTextOut;
+}
+
+extern "C" EXPORT const char* STDCALL AStyleGetVersion (void)
+{
+ return _version;
+}
+
+// ASTYLECON_LIB is defined to exclude "main" from the test programs
+#elif !defined(ASTYLECON_LIB)
+
+// ************************** main function ***************************************************
+
+int main(int argc, char** argv)
+{
+ ASFormatter formatter;
+ g_console = new ASConsole;
+
+ // process command line and options file
+ // build the vectors fileNameVector, optionsVector, and fileOptionsVector
+ processReturn returnValue = g_console->processOptions(argc, argv, formatter);
+
+ // check for end of processing
+ if (returnValue == END_SUCCESS)
+ return EXIT_SUCCESS;
+ if (returnValue == END_FAILURE)
+ {
+ (*_err) << "Artistic Style has terminated!" << endl;
+ return EXIT_FAILURE;
+ }
+
+ // if no files have been given, use cin for input and cout for output
+ if (g_console->fileNameVectorIsEmpty())
+ {
+ g_console->formatCinToCout(formatter);
+ return EXIT_SUCCESS;
+ }
+
+ // process entries in the fileNameVector
+ g_console->processFiles(formatter);
+
+ delete g_console;
+ return EXIT_SUCCESS;
+}
+
+#endif
diff --git a/support/highlight/src/core/astyle/astyle_main.h b/support/highlight/src/core/astyle/astyle_main.h
new file mode 100644
index 0000000000..1ec7ea57ff
--- /dev/null
+++ b/support/highlight/src/core/astyle/astyle_main.h
@@ -0,0 +1,268 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Copyright (C) 2006-2010 by Jim Pattee <jimp03@email.com>
+ * Copyright (C) 1998-2002 by Tal Davidson
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>
+ *
+ * This file is a part of Artistic Style - an indentation and
+ * reformatting tool for C, C++, C# and Java source files.
+ * <http://astyle.sourceforge.net>
+ *
+ * Artistic Style is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Artistic Style is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Artistic Style. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+#ifndef ASTYLE_MAIN_H
+#define ASTYLE_MAIN_H
+
+//----------------------------------------------------------------------------
+// headers
+//----------------------------------------------------------------------------
+
+#include <ctime>
+#include "astyle.h"
+
+#if defined(_MSC_VER) || defined(__DMC__)
+#include <sys/utime.h>
+#include <sys/stat.h>
+#else
+#include <utime.h>
+#include <sys/stat.h>
+#endif // end compiler checks
+
+#ifdef ASTYLE_JNI
+#include <jni.h>
+#ifndef ASTYLE_LIB // ASTYLE_LIB must be defined for ASTYLE_JNI
+#define ASTYLE_LIB
+#endif
+#endif // ASTYLE_JNI
+
+// for G++ implementation of string.compare:
+#if defined(__GNUC__) && __GNUC__ < 3
+#error - Use GNU C compiler release 3 or higher
+#endif
+
+// for namespace problem in version 5.0
+#if defined(_MSC_VER) && _MSC_VER < 1200 // check for V6.0
+#error - Use Microsoft compiler version 6 or higher
+#endif
+
+//using namespace astyle;
+
+namespace astyle
+{
+
+// return values for ASConsole
+enum processReturn { CONTINUE, END_SUCCESS, END_FAILURE };
+
+//----------------------------------------------------------------------------
+// ASStreamIterator class
+// typename will be istringstream for GUI and istream otherwise
+// ASSourceIterator is an abstract class defined in astyle.h
+//----------------------------------------------------------------------------
+
+template<typename T>
+class ASStreamIterator : public ASSourceIterator
+{
+ public:
+ bool checkForEmptyLine;
+
+ // function declarations
+ ASStreamIterator(T *in);
+ virtual ~ASStreamIterator();
+ bool getLineEndChange(int lineEndFormat) const;
+ string nextLine(bool emptyLineWasDeleted);
+ string peekNextLine();
+ void peekReset();
+ void saveLastInputLine();
+
+ private:
+ T * inStream; // pointer to the input stream
+ string buffer; // current input line
+ string prevBuffer; // previous input line
+ int eolWindows; // number of Windows line endings, CRLF
+ int eolLinux; // number of Linux line endings, LF
+ int eolMacOld; // number of old Mac line endings. CR
+ char outputEOL[4]; // next output end of line char
+ streamoff peekStart; // starting position for peekNextLine
+ bool prevLineDeleted; // the previous input line was deleted
+
+ public: // inline functions
+ bool compareToInputBuffer(const string &nextLine) const
+ { return (nextLine == prevBuffer); }
+ const char* getOutputEOL() const { return outputEOL; }
+ bool hasMoreLines() const { return !inStream->eof(); }
+};
+
+//----------------------------------------------------------------------------
+// ASConsole class for console build
+//----------------------------------------------------------------------------
+
+class ASConsole
+{
+ private: // variables
+ // command line options
+ bool isRecursive; // recursive option
+ string origSuffix; // suffix= option
+ bool noBackup; // suffix=none option
+ bool preserveDate; // preserve-date option
+ bool isVerbose; // verbose option
+ bool isQuiet; // quiet option
+ bool isFormattedOnly; // formatted lines only option
+ bool optionsFileRequired; // options= option
+ // other variables
+ bool hasWildcard; // file name includes a wildcard
+ size_t mainDirectoryLength; // directory length to be excluded in displays
+ bool filesAreIdentical; // input and output files are identical
+ bool lineEndsMixed; // outputhas mixed line ends
+ int linesOut; // number of output lines
+ int filesFormatted; // number of files formatted
+ int filesUnchanged; // number of files unchanged
+ char outputEOL[4]; // current line end
+ char prevEOL[4]; // previous line end
+
+ string optionsFileName; // file path and name of the options file to use
+ string targetDirectory; // path to the directory being processed
+ string targetFilename; // file name being processed
+
+ vector<string> excludeVector; // exclude from wildcard hits
+ vector<bool> excludeHitsVector; // exclude flags for eror reporting
+ vector<string> fileNameVector; // file paths and names from the command line
+ vector<string> optionsVector; // options from the command line
+ vector<string> fileOptionsVector; // options from the options file
+ vector<string> fileName; // files to be processed including path
+
+ public:
+ ASConsole() {
+ // command line options
+ isRecursive = false;
+ origSuffix = ".orig";
+ noBackup = false;
+ preserveDate = false;
+ isVerbose = false;
+ isQuiet = false;
+ isFormattedOnly = false;
+ optionsFileRequired = false;
+ // other variables
+ hasWildcard = false;
+ filesAreIdentical = true;
+ lineEndsMixed = false;
+ outputEOL[0] = '\0';
+ prevEOL[0] = '\0';
+ mainDirectoryLength = 0;
+ filesFormatted = 0;
+ filesUnchanged = 0;
+ linesOut = 0;
+ }
+
+ // functions
+ void convertLineEnds(ostringstream& out, int lineEnd);
+ void error(const char *why, const char* what) const;
+ void formatCinToCout(ASFormatter& formatter) const;
+ FileEncoding getFileEncoding(ifstream& in) const;
+ bool fileNameVectorIsEmpty();
+ int getFilesFormatted();
+ int getFilesUnchanged();
+ bool getIsFormattedOnly();
+ bool getIsQuiet();
+ bool getIsRecursive();
+ bool getIsVerbose();
+ bool getLineEndsMixed();
+ bool getNoBackup();
+ string getOptionsFileName();
+ bool getOptionsFileRequired();
+ string getOrigSuffix();
+ bool getPreserveDate();
+ void processFiles(ASFormatter &formatter);
+ processReturn processOptions(int argc, char** argv, ASFormatter &formatter);
+ void setIsFormattedOnly(bool state);
+ void setIsQuiet(bool state);
+ void setIsRecursive(bool state);
+ void setIsVerbose(bool state);
+ void setNoBackup(bool state);
+ void setOptionsFileName(string name);
+ void setOptionsFileRequired(bool state);
+ void setOrigSuffix(string suffix);
+ void setPreserveDate(bool state);
+ void standardizePath(string &path, bool removeBeginningSeparator=false) const;
+ bool stringEndsWith(const string &str, const string &suffix) const;
+ void updateExcludeVector(string suffixParam);
+
+ // for unit testing
+ vector<string> getExcludeVector();
+ vector<bool> getExcludeHitsVector();
+ vector<string> getFileNameVector();
+ vector<string> getOptionsVector();
+ vector<string> getFileOptionsVector();
+ vector<string> getFileName();
+
+ private:
+ void correctMixedLineEnds(ostringstream& out);
+ void formatFile(const string &fileName, ASFormatter &formatter);
+ string getCurrentDirectory(const string &fileName) const;
+ void getFileNames(const string &directory, const string &wildcard);
+ void getFilePaths(string &filePath);
+ void initializeOutputEOL(LineEndFormat lineEndFormat);
+ bool isPathExclued(const string &subPath);
+ void printBadEncoding(FileEncoding encoding) const;
+ void printHelp() const;
+ void printMsg(const string &msg) const;
+ void printVerboseHeader() const;
+ void printVerboseStats(clock_t startTime) const;
+ void removeFile(const char* fileName, const char* errMsg) const;
+ void renameFile(const char* oldFileName, const char* newFileName, const char* errMsg) const;
+ void setOutputEOL(LineEndFormat lineEndFormat, const char* currentEOL);
+ void sleep(int seconds) const;
+ int waitForRemove(const char* oldFileName) const;
+ int wildcmp(const char *wild, const char *data) const;
+ void writeOutputFile(const string &fileName, ostringstream &out) const;
+};
+
+
+//----------------------------------------------------------------------------
+// global function declarations
+// used by both console and library builds
+//----------------------------------------------------------------------------
+
+void importOptions(istream &in, vector<string> &optionsVector);
+void isOptionError(const string &arg, const string &errorInfo);
+bool isParamOption(const string &arg, const char *option);
+bool isParamOption(const string &arg, const char *option1, const char *option2);
+bool parseOption(astyle::ASFormatter &formatter, const string &arg, const string &errorInfo);
+
+template<typename ITER>
+bool parseOptions(astyle::ASFormatter &formatter, const ITER &optionsBegin,
+ const ITER &optionsEnd, const string &errorInfo);
+
+} // end of namespace astyle
+
+//----------------------------------------------------------------------------
+// declarations for java native interface (JNI) build
+// global because they are called externally and are NOT part of the namespace
+//----------------------------------------------------------------------------
+
+#ifdef ASTYLE_JNI
+void STDCALL javaErrorHandler(int errorNumber, char* errorMessage);
+char* STDCALL javaMemoryAlloc(unsigned long memoryNeeded);
+// the following function names are constructed from method names in the calling java program
+extern "C" EXPORT
+jstring STDCALL Java_AStyleInterface_AStyleGetVersion(JNIEnv* env, jclass);
+extern "C" EXPORT
+jstring STDCALL Java_AStyleInterface_AStyleMain
+(JNIEnv* env, jobject obj, jstring textInJava, jstring optionsJava);
+#endif // ASTYLE_JNI
+
+
+#endif // closes ASTYLE_MAIN_H
diff --git a/support/highlight/src/core/bbcodegenerator.cpp b/support/highlight/src/core/bbcodegenerator.cpp
new file mode 100644
index 0000000000..deab822660
--- /dev/null
+++ b/support/highlight/src/core/bbcodegenerator.cpp
@@ -0,0 +1,128 @@
+/***************************************************************************
+ bbcodegenarator.cpp - description
+ -------------------
+ begin : Jul 21 2009
+ copyright : (C) 2004-2009 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <sstream>
+
+#include "bbcodegenerator.h"
+
+using namespace std;
+
+namespace highlight
+{
+
+ BBCodeGenerator::BBCodeGenerator() : CodeGenerator ( BBCODE )
+ {
+ newLineTag = "\n";
+ spacer = " ";
+ }
+
+ BBCodeGenerator::~BBCodeGenerator() {}
+
+ string BBCodeGenerator::getHeader()
+ {
+ return string();
+ }
+
+ void BBCodeGenerator::printBody()
+ {
+ *out << "[size="<<getBaseFontSize()<<"]";
+ processRootState();
+ *out << "[/size]";
+ }
+
+ string BBCodeGenerator::getFooter()
+ {
+ return string();
+ }
+
+ string BBCodeGenerator::getOpenTag (const ElementStyle & elem )
+ {
+ ostringstream s;
+
+ s << "[color=#";
+ s << elem.getColour().getRed ( HTML )
+ << elem.getColour().getGreen ( HTML )
+ << elem.getColour().getBlue ( HTML )
+ << "]";
+
+ if ( elem.isBold() ) s << "[b]";
+ if ( elem.isItalic() ) s << "[i]";
+ if ( elem.isUnderline() ) s << "[u]";
+ return s.str();
+ }
+
+ string BBCodeGenerator::getCloseTag ( const ElementStyle &elem )
+ {
+ ostringstream s;
+ if ( elem.isBold() ) s << "[/b]";
+ if ( elem.isItalic() ) s << "[/i]";
+ if ( elem.isUnderline() ) s << "[/u]";
+ s << "[/color]";
+ return s.str();
+ }
+
+ void BBCodeGenerator::initOutputTags ()
+ {
+ openTags.push_back ( "");
+ openTags.push_back ( getOpenTag ( docStyle.getStringStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getNumberStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getSingleLineCommentStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getCommentStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getEscapeCharStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getDirectiveStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getDirectiveStringStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getLineStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getSymbolStyle() ) );
+
+ closeTags.push_back ( "" );
+ closeTags.push_back ( getCloseTag ( docStyle.getStringStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getNumberStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getSingleLineCommentStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getCommentStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getEscapeCharStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getDirectiveStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getDirectiveStringStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getLineStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getSymbolStyle() ) );
+ }
+
+ string BBCodeGenerator::maskCharacter ( unsigned char c )
+ {
+ return string ( 1, c );
+ }
+
+ string BBCodeGenerator::getKeywordOpenTag ( unsigned int styleID )
+ {
+ return getOpenTag (docStyle.getKeywordStyle ( langInfo.getKeywordClasses() [styleID] ) );
+ }
+
+ string BBCodeGenerator::getKeywordCloseTag ( unsigned int styleID )
+ {
+ return getCloseTag ( docStyle.getKeywordStyle ( langInfo.getKeywordClasses() [styleID] ) );
+ }
+
+}
diff --git a/support/highlight/src/core/bbcodegenerator.h b/support/highlight/src/core/bbcodegenerator.h
new file mode 100644
index 0000000000..49792984cf
--- /dev/null
+++ b/support/highlight/src/core/bbcodegenerator.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ bbcodegenerator.h - description
+ -------------------
+ begin : Jul 20 2009
+ copyright : (C) 2004-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef BBCODEGENERATOR_H
+#define BBCODEGENERATOR_H
+
+#include <string>
+
+#include "codegenerator.h"
+#include "charcodes.h"
+#include "version.h"
+
+namespace highlight
+{
+
+ /**
+ \brief This class generates BBCode.
+
+ It contains information about the resulting document structure (document
+ header and footer), the colour system, white space handling and text
+ formatting attributes.
+
+ * @author Andre Simon
+ */
+
+ class BBCodeGenerator : public highlight::CodeGenerator
+ {
+ public:
+ BBCodeGenerator();
+ ~BBCodeGenerator();
+
+ /** prints document header
+ */
+ string getHeader();
+
+ /** Prints document footer*/
+ string getFooter();
+
+ /** Prints document body*/
+ void printBody();
+
+ private:
+
+ /** \return escaped character*/
+ virtual string maskCharacter ( unsigned char );
+
+ /** @return BBcode open tags */
+ string getOpenTag (const ElementStyle & elem );
+
+ /** @return BBcode close tags */
+ string getCloseTag ( const ElementStyle &elem );
+
+ /** initialize tags in specific format according to colouring information provided in DucumentStyle */
+ void initOutputTags();
+
+ /** @param styleID current style ID
+ @return matching sequence to begin a new element formatting*/
+ string getKeywordOpenTag ( unsigned int styleID );
+
+ /** @param styleID current style ID
+ @return matching sequence to stop element formatting*/
+ string getKeywordCloseTag ( unsigned int styleID );
+ };
+
+}
+#endif
diff --git a/support/highlight/src/core/charcodes.h b/support/highlight/src/core/charcodes.h
new file mode 100644
index 0000000000..d112b7553e
--- /dev/null
+++ b/support/highlight/src/core/charcodes.h
@@ -0,0 +1,99 @@
+/***************************************************************************
+ charcodes.cpp - description
+ -------------------
+ begin : Wed Nov 24 2003
+ copyright : (C) 2003 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef CHAR_CODES
+#define CHAR_CODES
+
+#ifdef _WIN32
+
+#define AUML_LC 228
+#define OUML_LC 246
+#define UUML_LC 252
+
+#define AUML_UC 196
+#define OUML_UC 214
+#define UUML_UC 220
+
+
+#define AACUTE_LC 225
+#define EACUTE_LC 233
+#define OACUTE_LC 243
+#define UACUTE_LC 250
+
+#define AACUTE_UC 193
+#define EACUTE_UC 201
+#define OACUTE_UC 211
+#define UACUTE_UC 218
+
+#define AGRAVE_LC 224
+#define EGRAVE_LC 232
+#define OGRAVE_LC 242
+#define UGRAVE_LC 249
+
+#define AGRAVE_UC 192
+#define EGRAVE_UC 200
+#define OGRAVE_UC 210
+#define UGRAVE_UC 217
+
+#define SZLIG 223
+
+#else
+
+#define AUML_LC 164
+#define OUML_LC 182
+#define UUML_LC 188
+
+#define AUML_UC 132
+#define OUML_UC 150
+#define UUML_UC 156
+
+
+#define AACUTE_LC 161
+#define EACUTE_LC 169
+#define OACUTE_LC 179
+#define UACUTE_LC 186
+
+#define AACUTE_UC 129
+#define EACUTE_UC 137
+#define OACUTE_UC 147
+#define UACUTE_UC 154
+
+#define AGRAVE_LC 160
+#define EGRAVE_LC 168
+#define OGRAVE_LC 178
+#define UGRAVE_LC 185
+
+#define AGRAVE_UC 128
+#define EGRAVE_UC 136
+#define OGRAVE_UC 146
+#define UGRAVE_UC 153
+
+#define SZLIG 159
+
+#endif
+
+#endif
diff --git a/support/highlight/src/core/codegenerator.cpp b/support/highlight/src/core/codegenerator.cpp
new file mode 100644
index 0000000000..dfb63ec48e
--- /dev/null
+++ b/support/highlight/src/core/codegenerator.cpp
@@ -0,0 +1,1804 @@
+/***************************************************************************
+ codegenerator.cpp - description
+ -------------------
+ begin : Die Jul 9 2002
+ copyright : (C) 2002-2009 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <climits>
+#include <memory>
+
+#include "codegenerator.h"
+
+#include "htmlgenerator.h"
+#include "xhtmlgenerator.h"
+#include "rtfgenerator.h"
+#include "latexgenerator.h"
+#include "texgenerator.h"
+#include "xmlgenerator.h"
+#include "svggenerator.h"
+#include "bbcodegenerator.h"
+#include "re/Matcher.h"
+#include "astyle/astyle.h"
+#include "astyle/ASStreamIterator.h"
+
+#if !defined (QT)
+#include "ansigenerator.h"
+#include "xterm256generator.h"
+#endif
+
+using namespace std;
+
+namespace highlight
+{
+
+ const unsigned int CodeGenerator::NUMBER_BUILTIN_STATES = 10;
+
+ const string CodeGenerator::STY_NAME_STD="std";
+ const string CodeGenerator::STY_NAME_STR="str";
+ const string CodeGenerator::STY_NAME_NUM="num";
+ const string CodeGenerator::STY_NAME_SLC="slc";
+ const string CodeGenerator::STY_NAME_COM="com" ;
+ const string CodeGenerator::STY_NAME_ESC="esc" ;
+ const string CodeGenerator::STY_NAME_DIR="dir" ;
+ const string CodeGenerator::STY_NAME_DST="dstr";
+ const string CodeGenerator::STY_NAME_LIN="line";
+ const string CodeGenerator::STY_NAME_SYM="sym" ;
+
+ CodeGenerator * CodeGenerator::getInstance ( OutputType type )
+ {
+ CodeGenerator* generator=NULL;
+ switch ( type )
+ {
+ case HTML:
+ generator = new HtmlGenerator();
+ break;
+ case XHTML:
+ generator = new XHtmlGenerator();
+ break;
+ case TEX:
+ generator = new TexGenerator ();
+ break;
+ case LATEX:
+ generator = new LatexGenerator();
+ break;
+ case RTF:
+ generator = new RtfGenerator ();
+ break;
+ case XML:
+ generator = new XmlGenerator();
+ break;
+ case SVG:
+ generator = new SVGGenerator();
+ break;
+ case BBCODE:
+ generator = new BBCodeGenerator();
+ break;
+#if !defined (QT)
+ case ANSI:
+ generator = new AnsiGenerator();
+ break;
+ case XTERM256:
+ generator = new Xterm256Generator();
+ break;
+#endif
+ default:
+ break;
+ }
+ return generator;
+ }
+
+
+ CodeGenerator::CodeGenerator ( highlight::OutputType type )
+ :in ( NULL ),
+ out ( NULL ),
+ encoding ( "none" ),
+ docTitle ( "Source file" ),
+ maskWs ( false ),
+ excludeWs ( false ),
+ fragmentOutput ( false ),
+ showLineNumbers ( false ),
+ lineNumberFillZeroes ( false ),
+ printNewLines(true),
+ lineNumber ( 0 ),
+ lineNumberOffset ( 0 ),
+ includeStyleDef ( false ),
+ lineIndex ( 0 ),
+ lineNumberWidth ( 5 ),
+ maxLineCnt ( UINT_MAX ),
+ terminatingChar ( '\0' ),
+ formatter ( NULL ),
+ formattingEnabled ( false ),
+ formattingPossible ( false ),
+ validateInput ( false ),
+ tagsEnabled ( false ),
+ noTrailingNewLine(false),
+ keywordCase ( StringTools::CASE_UNCHANGED ),
+ eolDelimiter ('\n'),
+ outputType ( type )
+ {
+ }
+
+
+ CodeGenerator::~CodeGenerator()
+ {
+ delete formatter;
+ }
+
+
+ bool CodeGenerator::initTheme ( const string& themePath )
+ {
+ this->themePath=themePath;
+ bool loadOK = docStyle.load ( themePath );
+ //docStyles.insert(docStyles.begin(), docStyle); // main style must be first
+ initOutputTags();
+ return loadOK;
+ }
+
+
+ bool CodeGenerator::hasWhiteBGColour()
+ {
+ //Colour bgCol = docStyles.front().getBgColour();
+ Colour bgCol = docStyle.getBgColour();
+ return bgCol.getRed ( HTML ) == "ff" && bgCol.getGreen ( HTML ) == "ff" && bgCol.getBlue ( HTML ) == "ff";
+ }
+
+
+ const string& CodeGenerator::getStyleName()
+ {
+ return themePath;
+ }
+
+
+ void CodeGenerator::setLineNumberWidth ( int w )
+ {
+ lineNumberWidth=w;
+ }
+
+
+ int CodeGenerator::getLineNumberWidth()
+ {
+ return lineNumberWidth;
+ }
+
+
+ void CodeGenerator::setPrintLineNumbers ( bool flag, unsigned int startCnt )
+ {
+ showLineNumbers=flag;
+ lineNumberOffset = startCnt-1;
+ }
+
+
+ bool CodeGenerator::getPrintLineNumbers()
+ {
+ return showLineNumbers;
+ }
+
+
+ void CodeGenerator::setPrintZeroes ( bool flag )
+ {
+ lineNumberFillZeroes=flag;
+ }
+
+
+ bool CodeGenerator::getPrintZeroes()
+ {
+ return lineNumberFillZeroes;
+ }
+
+
+ void CodeGenerator::setIncludeStyle ( bool flag )
+ {
+ includeStyleDef = flag;
+ }
+
+ void CodeGenerator::disableTrailingNL ( bool flag )
+ {
+ noTrailingNewLine = flag;
+ }
+
+
+ void CodeGenerator::setStyleInputPath ( const string& path )
+ {
+ styleInputPath = path;
+ }
+
+
+ void CodeGenerator::setStyleOutputPath ( const string& path )
+ {
+ styleOutputPath = path;
+ }
+
+
+ const string& CodeGenerator::getStyleInputPath()
+ {
+ return styleInputPath;
+ }
+
+
+ const string& CodeGenerator::getStyleOutputPath()
+ {
+ return styleOutputPath;
+ }
+
+
+ void CodeGenerator::setFragmentCode ( bool flag )
+ {
+ fragmentOutput=flag;
+ }
+
+
+ bool CodeGenerator::getFragmentCode()
+ {
+ return fragmentOutput;
+ }
+
+
+ void CodeGenerator::setValidateInput ( bool flag )
+ {
+ validateInput=flag;
+ }
+
+
+ bool CodeGenerator::getValidateInput()
+ {
+ return validateInput;
+ }
+
+
+ void CodeGenerator::setBaseFont ( const string& s )
+ {
+ baseFont = s;
+ }
+
+
+ void CodeGenerator::setBaseFontSize ( const string& s )
+ {
+ baseFontSize = s ;
+ }
+
+ void CodeGenerator::setStartingNestedLang(const string &langName) {
+ embedLangStart = langName;
+ }
+
+
+ const string CodeGenerator::getBaseFont() const
+ {
+ if ( !baseFont.empty() ) return baseFont;
+ switch ( outputType )
+ {
+ case LATEX:
+ return "ttfamily";
+ break;
+ case TEX:
+ return "tt";
+ break;
+ default:
+ return "Courier New";
+ }
+ }
+
+
+ const string CodeGenerator::getBaseFontSize()
+ {
+ if ( baseFontSize.empty() && outputType != LATEX && outputType != TEX )
+ {
+ //return docStyles.front().getFontSize();
+ return docStyle.getFontSize();
+ }
+ else
+ {
+ return baseFontSize;
+ }
+ }
+
+
+ void CodeGenerator::setTitle ( const string & title )
+ {
+ if ( !title.empty() ) docTitle= title;
+ }
+
+
+ string CodeGenerator::getTitle()
+ {
+ return docTitle;
+ }
+
+
+ void CodeGenerator::setEncoding ( const string& encodingName )
+ {
+ encoding = encodingName;
+ }
+
+
+ bool CodeGenerator::formattingDisabled()
+ {
+ return !formattingEnabled;
+ }
+
+
+ void CodeGenerator::setMaxInputLineCnt ( unsigned int cnt )
+ {
+ maxLineCnt = cnt;
+ }
+
+
+ bool CodeGenerator::formattingIsPossible()
+ {
+ return formattingPossible;
+ }
+
+
+ void CodeGenerator::setPreformatting ( WrapMode lineWrappingStyle,
+ unsigned int lineLength,
+ int numberSpaces )
+ {
+ bool enableWrap = lineWrappingStyle!=WRAP_DISABLED;
+ bool replaceTabs = numberSpaces > 0;
+
+ if ( enableWrap || replaceTabs )
+ {
+ preFormatter.setWrap ( enableWrap );
+ preFormatter.setWrapIndentBraces ( lineWrappingStyle==WRAP_DEFAULT );
+ preFormatter.setWrapLineLength ( lineLength );
+ preFormatter.setReplaceTabs ( replaceTabs );
+ preFormatter.setNumberSpaces ( numberSpaces );
+ }
+ }
+
+
+ void CodeGenerator::setKeyWordCase ( StringTools::KeywordCase keyCase )
+ {
+ keywordCase = keyCase;
+ }
+
+
+ void CodeGenerator::addMarkedLine ( int lineNo, string& helpTxt )
+ {
+ markLines[lineNo] = helpTxt;
+ }
+
+
+ const LanguageDefinition &CodeGenerator::getLanguage()
+ {
+ return langInfo;
+ }
+
+
+ void CodeGenerator::setEOLDelimiter(char delim){
+ eolDelimiter = delim;
+ }
+
+
+ void CodeGenerator::reset()
+ {
+ lineIndex = 0;
+ lineNumber = 0;
+ line.clear();
+ preFormatter.reset();
+ inFile.clear();
+ outFile.clear();
+ hostLangDefPath.clear();
+ embedLangDefPath.clear();
+ printNewLines=true;
+ }
+
+
+ /** sucht vorwaerts ab Position searchPos Ziffer in s und liefert Integerwert
+ der gefundenen Zahl zurueck.
+ Im SymbolString stehen die den einzelnen Symbolen zugeordneten Konstanten
+ immer HINTER diesen Symbolen*/
+ State CodeGenerator::getState ( const string &s, unsigned int searchPos )
+ {
+ string::size_type pos = s.find_first_of ( "1234567890", searchPos+1 );
+ if ( pos==string::npos ) return _UNKNOWN;
+
+ string::size_type pos2 = s.find ( ' ', pos );
+ int result=_UNKNOWN;
+ StringTools::str2num<int> ( result, s.substr ( pos, pos2-pos ), std::dec );
+ return ( State ) result;
+ }
+
+
+ unsigned int CodeGenerator::getLineNumber()
+ {
+ return lineNumber;
+ }
+
+
+ bool CodeGenerator::readNewLine ( string &newLine )
+ {
+
+ bool eof;
+ if ( lineIndex ) terminatingChar=newLine[lineIndex-1];
+ if ( formattingPossible && formattingEnabled )
+ {
+ eof=!formatter->hasMoreLines();
+ if ( !eof )
+ {
+ newLine = formatter->nextLine();
+ }
+ }
+ // reformatting not enabled
+ else
+ {
+ eof = ! getline ( *in, newLine, eolDelimiter );
+ }
+
+ return eof || ( lineNumber == maxLineCnt );
+ }
+
+
+ void CodeGenerator::matchRegex ( const string &line )
+ {
+
+ regexGroups.clear();
+ int matchBegin=0;
+ int matchLen=0;
+ int groupID=0;
+
+ // cycle through all regex, save the start and ending indices to report them later
+ for ( unsigned int i=0; i<langInfo.getRegexElements().size(); i++ )
+ {
+ RegexElement *regexElem = langInfo.getRegexElements() [i];
+ auto_ptr<Matcher> matcher ( regexElem->rePattern->createMatcher ( line ) );
+
+ while ( matcher->findNextMatch() )
+ {
+ groupID = ( regexElem->capturingGroup<0 ) ? matcher->getGroupNum()-1 : regexElem->capturingGroup;
+ matchBegin = matcher->getStartingIndex ( groupID );
+ if ( matchBegin<0 ) continue;
+
+ matchLen = matcher->getEndingIndex ( groupID ) - matchBegin;
+ /*
+ std::cerr << "\nmatchBegin="<<1+ matchBegin
+ << " matchLen old" << ( matcher->getGroup(matcher->getGroupNum()-1).size())
+ << " matchLen new" << matchLen<<" group: "<<(matcher->getGroup(matcher->getGroupNum()-1))
+ << " group id= "<<regexElem->capturingGroup
+ << " lang= "<<regexElem->langName<<"\n";
+ cerr<<"match: "<<(matcher->getGroup(matcher->getGroupNum()-1))<<" id: "<<regexElem->open<<endl;
+ */
+ regexGroups.insert (
+ make_pair ( matchBegin+1, ReGroup ( regexElem->open, matchLen, regexElem->kwClass, regexElem->langName ) ) );
+ }
+ }
+ }
+
+
+ unsigned char CodeGenerator::getInputChar()
+ {
+ bool eol = lineIndex == line.length();
+
+ if ( eol )
+ {
+ bool eof=false;
+ if ( preFormatter.isEnabled() )
+ {
+ if ( !preFormatter.hasMoreLines() )
+ {
+ eof=readNewLine ( line );
+ preFormatter.setLine ( line );
+ }
+ line = preFormatter.getNextLine();
+ }
+ else
+ {
+ eof=readNewLine ( line );
+ }
+ lineIndex=0;
+ ++lineNumber;
+ //line=StringTools::trimRight ( line );
+ matchRegex ( line );
+
+ return ( eof ) ?'\0':'\n';
+ }
+
+ return line[lineIndex++];
+ }
+
+
+ State CodeGenerator::getCurrentState ()
+ {
+
+ unsigned char c='\0';
+
+ if ( token.length() ==0 )
+ {
+ c=getInputChar();
+ }
+ else
+ {
+ lineIndex-= ( token.length()-1 );
+ c=token[0];
+ }
+ if ( c=='\n' )
+ {
+ return _EOL; // End of line
+ }
+
+ if ( c=='\0' )
+ {
+ return _EOF; // End of file
+ }
+
+ if ( c==' ' || c=='\t' )
+ {
+ token= c;
+ return _WS;
+ }
+
+ /** TODO
+ COMMENT ... END 2 eintraege in langdef (ML_COMMENT_START=regex(), ML_COMMENT_END=regex())
+ weil comment sonst als identifier erkannt wird
+ */
+
+ // Test if a regular expression was found at the current position
+ if ( !regexGroups.empty() )
+ {
+ if ( regexGroups.count ( lineIndex ) )
+ {
+ token = line.substr ( lineIndex-1, regexGroups[lineIndex].length );
+ unsigned int oldIndex= lineIndex;
+ if ( regexGroups[oldIndex].length>1 ) lineIndex+= regexGroups[oldIndex].length-1;
+
+
+ if ( regexGroups[oldIndex].state==EMBEDDED_CODE_BEGIN) {
+ embedLangDefPath = langInfo.getNewPath(regexGroups[oldIndex].name);
+ }
+
+ if ( regexGroups[oldIndex].state==IDENTIFIER_BEGIN || regexGroups[oldIndex].state==KEYWORD )
+ {
+ string reservedWord= ( langInfo.isIgnoreCase() ) ? StringTools::change_case ( token ) :token;
+ currentKeywordClass=langInfo.isKeyword ( reservedWord );
+ if ( !currentKeywordClass && regexGroups[oldIndex].state==KEYWORD )
+ currentKeywordClass = regexGroups[oldIndex].kwClass;
+ return ( currentKeywordClass ) ? KEYWORD : STANDARD;
+ }
+ else
+ {
+ return regexGroups[oldIndex].state;
+ }
+ }
+ }
+
+ unsigned int symbolLength;
+ size_t symbolPos;
+ size_t symbolFind;
+ string symbols=langInfo.getSymbolString();
+
+ //TODO this while loop kills performance - adjust search algorithm
+
+ symbolPos = symbols.find ( c );
+ // search symbols (comment delimiters, directives etc.)
+ // before keywords, because alphabetic chars may be part of symbols, too
+
+ while ( symbolPos!= string::npos && ! std::isdigit(c)) // isdigit: fix rexx issue
+ {
+ symbolFind = symbols.find ( ' ', symbolPos );
+ if ( symbolFind==string::npos ) break;
+ symbolLength=symbolFind-symbolPos;
+ token = symbols.substr ( symbolPos, symbolLength );
+ // Abfrage nach Leerzeichen in SymbolString verhindert falsches
+ // Erkennen von Symbolteilen:
+ if ( lineIndex && token == line.substr ( lineIndex-1, symbolLength )
+ && symbols[symbolPos-1]==' ' )
+ {
+ lineIndex += ( symbolLength-1 );
+ return getState ( symbols, symbolPos );
+ }
+ else
+ {
+ symbolPos = symbols.find_first_not_of ( ' ',symbols.find ( ' ',symbolPos ) );
+ }
+ }
+
+ // Character not referring to any state
+ token = c;
+ return STANDARD;
+ }
+
+
+ //it is faster to pass ostream reference
+ void CodeGenerator::maskString ( ostream& ss, const string & s )
+ {
+ for ( unsigned int i=0;i< s.length();i++ )
+ {
+ ss << maskCharacter ( s[i] );
+ }
+ }
+
+
+ void CodeGenerator::printMaskedToken ( bool addMetaInfo, bool flushWhiteSpace,
+ StringTools::KeywordCase tcase )
+ {
+ if ( flushWhiteSpace ) flushWs();
+
+ if ( addMetaInfo && tagsEnabled )
+ {
+ bool insertMetaInfo=metaInfo.tagExists ( token );
+ if ( insertMetaInfo ) *out<<getMetaInfoOpenTag ( metaInfo.getTagInfo ( token ) );
+ maskString ( *out, StringTools::change_case ( token, tcase ) );
+ if ( insertMetaInfo ) *out<<getMetaInfoCloseTag();
+ }
+ else
+ {
+ maskString ( *out, StringTools::change_case ( token, tcase ) );
+ }
+ token.clear();
+ }
+
+
+ bool CodeGenerator::styleFound()
+ {
+ return docStyle.found();
+ //return docStyles.front().found();
+ }
+
+
+ bool CodeGenerator::printIndexFile ( const vector<string> &fileList,
+ const string &outPath )
+ {
+ return true;
+ }
+
+
+ bool CodeGenerator::initIndentationScheme ( const string &indentScheme )
+ {
+
+ if ( formatter!=NULL )
+ {
+ return true;
+ }
+
+ if ( !indentScheme.size() ) return false;
+
+ formatter=new astyle::ASFormatter();
+
+ formatter->setParensHeaderPaddingMode(true);
+
+ if ( indentScheme=="allman" || indentScheme=="bsd" || indentScheme=="ansi" )
+ {
+ formatter->setFormattingStyle ( astyle::STYLE_ALLMAN );
+ }
+ else if ( indentScheme=="kr"||indentScheme=="k&r"||indentScheme=="k/r" )
+ {
+ formatter->setFormattingStyle ( astyle::STYLE_KandR );
+ }
+ else if ( indentScheme=="java" )
+ {
+ formatter->setFormattingStyle ( astyle::STYLE_JAVA );
+ }
+ else if ( indentScheme=="stroustrup" )
+ {
+ formatter->setFormattingStyle ( astyle::STYLE_STROUSTRUP );
+ }
+ else if ( indentScheme=="whitesmith" )
+ {
+ formatter->setFormattingStyle ( astyle::STYLE_WHITESMITH );
+ }
+ else if ( indentScheme=="banner" )
+ {
+ formatter->setFormattingStyle ( astyle::STYLE_BANNER );
+ }
+ else if ( indentScheme=="gnu" )
+ {
+ formatter->setFormattingStyle ( astyle::STYLE_GNU );
+ }
+ else if ( indentScheme=="linux" )
+ {
+ formatter->setFormattingStyle ( astyle::STYLE_LINUX );
+ }
+ else if ( indentScheme=="horstmann" )
+ {
+ formatter->setFormattingStyle ( astyle::STYLE_HORSTMANN );
+ }
+ else if ( indentScheme=="otbs" || indentScheme=="1tbs")
+ {
+ formatter->setFormattingStyle ( astyle::STYLE_1TBS );
+ }
+ else
+ {
+ return false;
+ }
+
+ return formattingEnabled=true;
+ }
+
+
+ LoadResult CodeGenerator::loadLanguage ( const string& langDefPath )
+ {
+ bool reloadNecessary= langInfo.needsReload ( langDefPath );
+ if ( reloadNecessary )
+ {
+ //cerr<<"LOADING"<<langDefPath<<endl;
+ if ( !langInfo.load ( langDefPath ) )
+ {
+ return langInfo.getFailedRegex().size() ? LOAD_FAILED_REGEX : LOAD_FAILED;
+ }
+
+ formattingPossible=langInfo.enableReformatting();
+
+ if ( openTags.size() >NUMBER_BUILTIN_STATES )
+ {
+ // remove dynamic keyword tag delimiters of the old language definition
+ vector<string>::iterator keyStyleOpenBegin =
+ openTags.begin() + NUMBER_BUILTIN_STATES;
+ vector<string>::iterator keyStyleCloseBegin =
+ closeTags.begin() + NUMBER_BUILTIN_STATES;
+ openTags.erase ( keyStyleOpenBegin, openTags.end() );
+ closeTags.erase ( keyStyleCloseBegin, closeTags.end() );
+ }
+ // add new keyword tag delimiters
+ for ( unsigned int i=0;i< langInfo.getKeywordClasses().size(); i++ )
+ {
+ openTags.push_back ( getKeywordOpenTag ( i ) );
+ closeTags.push_back ( getKeywordCloseTag ( i ) );
+ }
+ }
+ return ( reloadNecessary) ? LOAD_NEW : LOAD_NONE;
+ }
+
+
+ bool CodeGenerator::initTagInformation ( const string& ctagsPath )
+ {
+ if ( tagsEnabled ) return true; // load tag info once
+ tagsEnabled = metaInfo.load ( ctagsPath );
+ return tagsEnabled;
+ }
+
+
+ bool CodeGenerator::validateInputStream()
+ {
+ if ( !in ) return false;
+
+ // it is not possible to move stream pointer back with stdin
+ if ( ( int ) in->tellg() == -1 ) // -1 : stdin
+ return true;
+
+ // Sources: http://en.wikipedia.org/wiki/Magic_number_(programming)
+ // Magic configuration of "file"
+ // This is intended for web plugins - only check filetypes often found in the net
+ char magic_gif[] = {'G','I','F','8', 0};
+ char magic_png[] = {0x89,'P','N','G', 0};
+ char magic_java[] = {0xCA,0xFE,0xBA,0xBE, 0};
+ char magic_jpeg[] = {0xFF,0xD8,0xFF, 0};
+ char magic_bmp[] = {'B','M', 0};
+ char magic_pdf[] = {'%','P','D','F', 0};
+ char magic_utf8[] = {0xEF,0xBB,0xBF,0};
+ char magic_rar[] = {'R','a','r','!', 0};
+ char magic_zip[] = {'P','K',0x03,0x04, 0};
+ char magic_ace[] = {'*','*','A','C','E','*','*', 0};
+ char magic_tgz[] = {0x8b,0x1f, 0x00, 0x08, 0};
+ char magic_bzip[] = {'B','Z', 0};
+
+ char* magic_table[] = {magic_utf8,
+ magic_gif, magic_png, magic_jpeg, magic_bmp, magic_pdf,
+ magic_java,
+ magic_rar, magic_zip, magic_ace, magic_tgz, magic_bzip,
+ 0
+ };
+
+ char buffer [10]={0};
+ in->read ( buffer,8 ); //only read the first 8 bytes of input stream
+
+ int magic_index=0;
+ while ( magic_table[magic_index] )
+ {
+ if ( !strncmp ( buffer, magic_table[magic_index], strlen ( magic_table[magic_index] ) ) )
+ {
+ break;
+ }
+ magic_index++;
+ }
+ int streamReadPos=0;
+ if ( magic_table[magic_index] == magic_utf8 )
+ {
+ //setEncoding("utf-8");
+ streamReadPos=3; // remove UTF-8 magic number from output
+ }
+
+ in -> seekg ( streamReadPos, ios::beg );
+ in-> clear(); // clear fail bit to continue reading
+
+ return !magic_table[magic_index] // points to 0 if no pattern was found
+ || magic_table[magic_index] == magic_utf8;
+ }
+
+
+ ParseError CodeGenerator::generateFile ( const string &inFileName,
+ const string &outFileName )
+ {
+ if ( !docStyle.found() )
+ {
+ return BAD_STYLE;
+ }
+
+ reset();
+
+ ParseError error=PARSE_OK;
+
+ inFile=inFileName;
+ outFile=outFileName;
+ in = ( inFileName.empty() ? &cin :new ifstream ( inFileName.c_str() ) );
+
+ if ( validateInput )
+ if ( !validateInputStream() ) error= BAD_INPUT;
+
+ if ( !in->fail() && error==PARSE_OK )
+ {
+ out = ( outFileName.empty() ? &cout :new ofstream ( outFileName.c_str() ) );
+ if ( out->fail() )
+ {
+ error=BAD_OUTPUT;
+ }
+ }
+
+ if ( in->fail() )
+ {
+ error=BAD_INPUT;
+ }
+
+ if ( error==PARSE_OK )
+ {
+ if ( formatter != NULL )
+ {
+ formatter->init ( new astyle::ASStreamIterator ( in ) );
+ }
+ if ( ! fragmentOutput )
+ {
+ *out << getHeader();
+ }
+
+ printBody();
+
+ if ( ! fragmentOutput )
+ {
+ *out << getFooter();
+ }
+ }
+
+ if ( !outFileName.empty() )
+ {
+ delete out; out=NULL;
+ }
+ if ( !inFileName.empty() )
+ {
+ delete in; in=NULL;
+ }
+ return error;
+ }
+
+
+ string CodeGenerator::generateString ( const string &input )
+ {
+
+ if ( !docStyle.found() )
+ {
+ return "";
+ }
+
+ reset();
+
+ in = new istringstream ( input );
+ out = new ostringstream ();
+
+ if ( in->fail() || out->fail() )
+ {
+ return "";
+ }
+
+ if ( formatter != NULL )
+ {
+ formatter->init ( new astyle::ASStreamIterator ( in ) );
+ }
+ if ( ! fragmentOutput )
+ {
+ *out << getHeader();
+ }
+
+ printBody();
+
+ if ( ! fragmentOutput )
+ {
+ *out << getFooter();
+ }
+
+ string result = static_cast<ostringstream*> ( out )->str();
+
+ delete out; out=NULL;
+ delete in; in=NULL;
+
+ return result;
+ }
+
+
+ string CodeGenerator::generateStringFromFile ( const string &inFileName )
+ {
+
+ if ( !docStyle.found() )
+ {
+ return "";
+ }
+
+ reset();
+
+ inFile = inFileName;
+ in = new ifstream ( inFileName.c_str() );
+ out = new ostringstream ();
+
+ if ( in->fail() || out->fail() )
+ {
+ return "";
+ }
+
+ if ( validateInput && !validateInputStream() )
+ {
+ return "ERROR: detected binary input";
+ }
+
+ if ( formatter != NULL )
+ {
+ formatter->init ( new astyle::ASStreamIterator ( in ) );
+ }
+ if ( ! fragmentOutput )
+ {
+ *out << getHeader();
+ }
+
+ printBody();
+
+ if ( ! fragmentOutput )
+ {
+ *out << getFooter();
+ }
+
+ string result = static_cast<ostringstream*> ( out )->str();
+
+ delete out; out=NULL;
+ delete in; in=NULL;
+
+ return result;
+ }
+
+
+ unsigned int CodeGenerator::getStyleID ( State s, unsigned int kwClassID )
+ {
+ if ( s==KEYWORD && kwClassID )
+ {
+ return NUMBER_BUILTIN_STATES + kwClassID-1;
+ }
+ return ( unsigned int ) s ;
+ }
+
+
+ void CodeGenerator::openTag ( State s )
+ {
+ *out << openTags[ ( unsigned int ) s];
+ currentState=s;
+ }
+
+
+ void CodeGenerator::closeTag ( State s )
+ {
+ *out << closeTags[ ( unsigned int ) s];
+ flushWs();
+ currentState=_UNKNOWN;
+ }
+
+
+ void CodeGenerator::openKWTag ( unsigned int kwClassID )
+ {
+ *out << openTags.at(getStyleID ( KEYWORD, kwClassID ) );
+ currentState=KEYWORD;
+ }
+
+
+ void CodeGenerator::closeKWTag ( unsigned int kwClassID )
+ {
+ *out << closeTags.at(getStyleID ( KEYWORD, kwClassID ) );
+ flushWs();
+ currentState=_UNKNOWN;
+ }
+
+ void CodeGenerator::loadEmbeddedLang(const string&embedLangDefPath){
+ //save path of host language
+ if (hostLangDefPath.empty()) {
+ hostLangDefPath =langInfo.getCurrentPath();
+ }
+ //load syntax of embedded langage
+ loadLanguage(embedLangDefPath);
+ //pass end delimiter regex to syntax description
+ langInfo.restoreLangEndDelim(embedLangDefPath);
+ }
+
+///////////////////////////////////////////////////////////////////////////////
+
+ void CodeGenerator::processRootState()
+ {
+
+ bool eof=false,
+ firstLine=true; // avoid newline before printing the first output line
+
+ if ( langInfo.highlightingDisabled() )
+ {
+ string line;
+ while ( getline ( *in, line ) )
+ {
+ ++lineNumber;
+ insertLineNumber ( !firstLine );
+ flushWs();
+ firstLine=false;
+ maskString ( *out, line );
+ }
+ *out << flush;
+ return;
+ }
+
+ if (!embedLangStart.empty()) loadEmbeddedLang(langInfo.getNewPath(embedLangStart));
+
+ State state=STANDARD;
+
+ openTag ( STANDARD );
+ do
+ {
+ // determine next state
+ state= getCurrentState();
+
+ // handle current state
+ switch ( state )
+ {
+ case KEYWORD:
+ closeTag ( STANDARD );
+ eof=processKeywordState ( state );
+ openTag ( STANDARD );
+ break;
+ case NUMBER:
+ closeTag ( STANDARD );
+ eof=processNumberState();
+ openTag ( STANDARD );
+ break;
+ case ML_COMMENT:
+ closeTag ( STANDARD );
+ eof=processMultiLineCommentState();
+ openTag ( STANDARD );
+ break;
+ case SL_COMMENT:
+ closeTag ( STANDARD );
+ eof=processSingleLineCommentState();
+ openTag ( STANDARD );
+ break;
+ case STRING:
+ closeTag ( STANDARD );
+ eof=processStringState ( STANDARD );
+ openTag ( STANDARD );
+ break;
+ case DIRECTIVE:
+ closeTag ( STANDARD );
+ eof=processDirectiveState();
+ openTag ( STANDARD );
+ break;
+ case ESC_CHAR:
+ if ( langInfo.allowExtEscSeq() )
+ {
+ closeTag ( STANDARD );
+ eof=processEscapeCharState();
+ openTag ( STANDARD );
+ }
+ else
+ {
+ printMaskedToken();
+ }
+ break;
+ case SYMBOL:
+ closeTag ( STANDARD );
+ eof=processSymbolState();
+ openTag ( STANDARD );
+ break;
+ case EMBEDDED_CODE_BEGIN:
+ case EMBEDDED_CODE_END:
+ closeTag ( STANDARD );
+ eof=processSyntaxChangeState(state);
+ openTag ( STANDARD );
+ break;
+ case _EOL:
+ insertLineNumber ( !firstLine );
+ firstLine=false;
+ break;
+ case _EOF:
+ eof=true;
+ break;
+ case _WS:
+ processWsState();
+ break;
+ default:
+ printMaskedToken ( true );
+ break;
+ }
+ }
+ while ( !eof );
+ closeTag ( STANDARD );
+ printNewLines = !noTrailingNewLine;
+ *out << getNewLine();
+ *out << flush;
+ }
+
+ bool CodeGenerator::processSyntaxChangeState(State myState)
+ {
+ State newState=STANDARD;
+ bool eof=false,
+ exitState=false;
+ openTag ( KEYWORD );
+ do
+ {
+ if (myState==EMBEDDED_CODE_BEGIN) {
+ loadEmbeddedLang(embedLangDefPath);
+
+ //test current line again to match tokens of the embedded language
+ matchRegex(line);
+
+ }
+ else if (myState==EMBEDDED_CODE_END) {
+ // load host language syntax
+ loadLanguage(hostLangDefPath);
+ //test current line again to match tokens of the host language
+ matchRegex(line);
+
+ }
+
+ printMaskedToken ( false, newState!=_WS );
+ newState= getCurrentState();
+ switch ( newState )
+ {
+ case _WS:
+ processWsState();
+ break;
+ case _EOL:
+ insertLineNumber();
+ exitState=true;
+ break;
+ case _EOF:
+ eof = true;
+ break;
+ default:
+ exitState=true;
+ break;
+ }
+ }
+ while ( ( !exitState ) && ( !eof ) );
+
+ closeTag ( KEYWORD );
+ return eof;
+ }
+
+
+ bool CodeGenerator::processKeywordState ( State myState )
+ {
+ State newState=STANDARD;
+ unsigned int myClassID=currentKeywordClass;
+ bool eof=false,
+ exitState=false;
+
+ openKWTag ( myClassID );
+ do
+ {
+ printMaskedToken ( true, newState!=_WS,
+ ( langInfo.isIgnoreCase() ) ? keywordCase : StringTools::CASE_UNCHANGED );
+ newState= getCurrentState();
+ switch ( newState )
+ {
+ case _WS:
+ processWsState();
+ break;
+ case _EOL:
+ insertLineNumber();
+ exitState=true;
+ break;
+ case _EOF:
+ eof = true;
+ break;
+ case KEYWORD_END:
+ exitState=true;
+ break;
+ default:
+ exitState= ( myClassID!=currentKeywordClass ) || ( myState!=newState );
+ break;
+ }
+ }
+ while ( ( !exitState ) && ( !eof ) );
+
+ closeKWTag ( myClassID );
+
+ currentKeywordClass=0;
+ return eof;
+ }
+
+
+ bool CodeGenerator::processNumberState()
+ {
+ State newState=STANDARD;
+ bool eof=false,
+ exitState=false;
+ openTag ( NUMBER );
+ do
+ {
+ printMaskedToken ( false, newState!=_WS );
+ newState= getCurrentState();
+ switch ( newState )
+ {
+ case _WS:
+ processWsState();
+ break;
+ case _EOL:
+ insertLineNumber();
+ exitState=true;
+ break;
+ case _EOF:
+ eof = true;
+ break;
+ default:
+ exitState=newState!=NUMBER;
+ break;
+ }
+ }
+ while ( ( !exitState ) && ( !eof ) );
+
+ closeTag ( NUMBER );
+ return eof;
+ }
+
+
+ bool CodeGenerator::processMultiLineCommentState()
+ {
+ int commentCount=1;
+ int delimPairID = langInfo.getDelimiterPairID ( token );
+ State newState=STANDARD;
+ bool eof=false, exitState=false;
+ openTag ( ML_COMMENT );
+ do
+ {
+ printMaskedToken ( false, newState!=_WS );
+ newState= getCurrentState();
+
+ switch ( newState )
+ {
+ case _WS:
+ processWsState();
+ break;
+ case _EOL:
+ wsBuffer += closeTags[ML_COMMENT];
+ insertLineNumber();
+ wsBuffer += openTags[ML_COMMENT];
+ break;
+ case _EOF:
+ eof = true;
+ break;
+ case ML_COMMENT:
+ if ( langInfo.allowNestedMLComments() )
+ {
+ ++commentCount;
+ }
+ // if delimiters are equal, close the comment by continueing to
+ // ML_COMMENT_END section
+ if ( langInfo.delimiterIsDistinct ( ML_COMMENT ) ) break;
+
+ case ML_COMMENT_END:
+ if ( delimPairID!=langInfo.getDelimiterPairID ( token ) ) break;
+ commentCount--;
+ if ( !commentCount )
+ {
+ printMaskedToken();
+ exitState=true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ while ( ( !exitState ) && ( !eof ) );
+
+ closeTag ( ML_COMMENT );
+ return eof;
+ }
+
+
+ bool CodeGenerator::processSingleLineCommentState()
+ {
+
+ if ( checkSpecialCmd() )
+ {
+ return in->bad(); // if input stream is bad, report eof to calling method
+ }
+
+ State newState=STANDARD;
+ bool eof=false, exitState=false;
+
+ openTag ( SL_COMMENT );
+ do
+ {
+ printMaskedToken ( false, newState!=_WS );
+ newState= getCurrentState();
+
+ switch ( newState )
+ {
+ case _WS:
+ processWsState();
+ break;
+ case _EOL:
+ printMaskedToken();
+ if ( preFormatter.isEnabled() && preFormatter.isWrappedLine ( lineNumber-1 ) )
+ {
+ exitState=false;
+ }
+ else
+ {
+ exitState=true;
+ }
+ if ( !exitState ) wsBuffer += closeTags[SL_COMMENT];
+ insertLineNumber();
+ if ( !exitState ) wsBuffer += openTags[SL_COMMENT];
+
+ break;
+ case _EOF:
+ eof = true;
+ break;
+ default:
+ break;
+ }
+ }
+ while ( ( !exitState ) && ( !eof ) );
+
+ closeTag ( SL_COMMENT );
+ return eof;
+ }
+
+
+ bool CodeGenerator::processDirectiveState()
+ {
+ State newState=STANDARD;
+ bool eof=false, exitState=false;
+
+ openTag ( DIRECTIVE );
+ do
+ {
+ printMaskedToken ( false, newState!=_WS );
+ newState= getCurrentState();
+ switch ( newState )
+ {
+ case _WS:
+ processWsState();
+ break;
+ case DIRECTIVE_END:
+ printMaskedToken();
+ exitState=true;
+ break;
+ case _EOL:
+ printMaskedToken();
+ if ( preFormatter.isEnabled() && preFormatter.isWrappedLine ( lineNumber-1 ) )
+ {
+ exitState=false;
+ }
+ else
+ {
+ exitState= ( terminatingChar!=langInfo.getContinuationChar() );
+ }
+ if ( !exitState ) wsBuffer += closeTags[DIRECTIVE];
+ insertLineNumber();
+ if ( !exitState ) wsBuffer += openTags[DIRECTIVE];
+ break;
+ case ML_COMMENT:
+ closeTag ( DIRECTIVE );
+ eof= processMultiLineCommentState();
+ openTag ( DIRECTIVE );
+ break;
+ case SL_COMMENT:
+ closeTag ( DIRECTIVE );
+ eof= processSingleLineCommentState();
+ openTag ( DIRECTIVE );
+ exitState=true;
+ break;
+ case STRING:
+ closeTag ( DIRECTIVE );
+ eof=processStringState ( DIRECTIVE );
+ openTag ( DIRECTIVE );
+ break;
+ case _EOF:
+ eof = true;
+ break;
+ default:
+ break;
+ }
+ }
+ while ( ( !exitState ) && ( !eof ) );
+
+ closeTag ( DIRECTIVE );
+ return eof;
+ }
+
+
+ bool CodeGenerator::processStringState ( State oldState )
+ {
+ State newState=STANDARD;
+ bool eof=false, exitState=false;
+ bool returnedFromOtherState=false;
+ // Test if character before string open delimiter token equals to the
+ // raw string prefix (Example: r" ", r""" """ in Python)
+ bool isRawString=false;
+ if ( lineIndex>token.length() )
+ {
+ isRawString = line[lineIndex-token.length()-1]==langInfo.getRawStringPrefix();
+ }
+ int delimPairID = langInfo.getDelimiterPairID ( token );
+ State myState= ( oldState==DIRECTIVE ) ? DIRECTIVE_STRING : STRING;
+ openTag ( myState );
+ do
+ {
+ // true if last token was an escape char
+ if ( !returnedFromOtherState )
+ {
+ printMaskedToken ( false, newState!=_WS );
+ }
+ returnedFromOtherState=false;
+ newState= getCurrentState();
+
+ switch ( newState )
+ {
+ case _WS:
+ processWsState();
+ break;
+ case _EOL:
+ wsBuffer += closeTags[myState];
+ insertLineNumber();
+ wsBuffer += openTags[myState];
+ break;
+ case STRING_END:
+ exitState= true;
+ printMaskedToken();
+ break;
+ case STRING:
+ // if there exist multiple string delimiters, close string if
+ // current delimiters is equal to the opening delimiter
+ exitState = ( delimPairID==langInfo.getDelimiterPairID ( token ) );
+ printMaskedToken();
+ break;
+ case ESC_CHAR:
+ if ( !isRawString )
+ {
+ closeTag ( myState );
+ eof=processEscapeCharState();
+ openTag ( myState );
+ returnedFromOtherState=true;
+ }
+ break;
+ case _EOF:
+ eof = true;
+ break;
+ default:
+ printMaskedToken();
+ break;
+ }
+ }
+ while ( ( !exitState ) && ( !eof ) );
+
+ closeTag ( myState );
+ return eof;
+ }
+
+
+ bool CodeGenerator::processSymbolState()
+ {
+
+ State newState=STANDARD;
+ bool eof=false,
+ exitState=false;
+
+ openTag ( SYMBOL );
+ do
+ {
+ printMaskedToken ( false, newState!=_WS );
+ newState= getCurrentState();
+ switch ( newState )
+ {
+ case _WS:
+ processWsState();
+ break;
+ case _EOL:
+ insertLineNumber();
+ exitState=true;
+ break;
+ case _EOF:
+ eof = true;
+ break;
+ default:
+ exitState=newState!=SYMBOL;
+ break;
+ }
+ }
+ while ( ( !exitState ) && ( !eof ) );
+
+ closeTag ( SYMBOL );
+ return eof;
+ }
+
+
+ bool CodeGenerator::processEscapeCharState()
+ {
+ State newState=STANDARD;
+ bool eof=false, exitState=false;
+ openTag ( ESC_CHAR );
+ do
+ {
+ printMaskedToken ( false, newState!=_WS );
+ newState= getCurrentState();
+ switch ( newState )
+ {
+ case _EOL:
+ insertLineNumber();
+ exitState=true;
+ break;
+ case _WS:
+ processWsState();
+ break;
+ case _EOF:
+ eof = true;
+ break;
+ default:
+ exitState=newState!=ESC_CHAR;
+ break;
+ }
+ }
+ while ( ( !exitState ) && ( !eof ) );
+
+ closeTag ( ESC_CHAR );
+ return eof;
+ }
+
+
+ void CodeGenerator::processWsState()
+ {
+ if ( !maskWs )
+ {
+ wsBuffer += token;
+ token.clear();
+ return;
+ }
+ flushWs();
+ int cntWs=0;
+ lineIndex--;
+
+ // while (iswspace(line[lineIndex]) ) {
+ while ( line[lineIndex]==' ' || line[lineIndex]=='\t' )
+ {
+ ++cntWs;
+ ++lineIndex;
+ }
+
+ if ( cntWs>1 )
+ {
+ unsigned int styleID=getStyleID ( currentState, currentKeywordClass );
+ if ( excludeWs && styleID!=_UNKNOWN )
+ {
+ *out << closeTags[styleID];
+ }
+ *out << maskWsBegin;
+ for ( int i=0; i<cntWs; i++ )
+ {
+ *out << spacer;
+ }
+ *out << maskWsEnd;
+ if ( excludeWs && styleID!=_UNKNOWN )
+ {
+ *out << openTags[styleID];
+ }
+ }
+ else
+ {
+ *out << spacer; //Bugfix fehlender Space nach Strings
+ }
+ token.clear();
+ }
+
+
+ void CodeGenerator::flushWs()
+ {
+ *out<<wsBuffer;
+ wsBuffer.clear();
+ }
+
+
+ string CodeGenerator::getNewLine()
+ {
+ return (printNewLines) ? newLineTag : "";
+ }
+
+
+ void CodeGenerator::insertLineNumber ( bool insertNewLine )
+ {
+
+ if ( insertNewLine )
+ {
+ wsBuffer += getNewLine();
+ }
+
+ if ( showLineNumbers )
+ {
+ ostringstream os;
+ ostringstream numberPrefix;
+ if ( lineNumberFillZeroes )
+ {
+ os.fill ( '0' );
+ }
+ os <<setw ( getLineNumberWidth() ) << right << lineNumber+lineNumberOffset;
+
+ numberPrefix << openTags[LINENUMBER];
+ maskString ( numberPrefix, os.str() );
+ numberPrefix << spacer
+ << closeTags[LINENUMBER];
+
+ wsBuffer += numberPrefix.str();
+ }
+ }
+
+
+ unsigned int CodeGenerator::getLineIndex()
+ {
+ return lineIndex;
+ }
+
+
+ bool CodeGenerator::printExternalStyle ( const string &outFile )
+ {
+ if ( !includeStyleDef && langInfo.highlightingEnabled() )
+ {
+ ostream *cssOutFile = ( outFile.empty() ? &cout :new ofstream ( outFile.c_str() ) );
+ if ( !cssOutFile->fail() )
+ {
+ *cssOutFile << styleCommentOpen
+ <<" Style definition file generated by highlight "
+ << HIGHLIGHT_VERSION << ", " << HIGHLIGHT_URL
+ << " " << styleCommentClose << "\n";
+ *cssOutFile << "\n" << styleCommentOpen
+ << " Highlighting theme definition: "
+ << styleCommentClose << "\n\n"
+ << getStyleDefinition()
+ << "\n";
+ *cssOutFile << readUserStyleDef();
+ if ( !outFile.empty() ) delete cssOutFile;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ string CodeGenerator::readUserStyleDef()
+ {
+ ostringstream ostr;
+ if ( !styleInputPath.empty() )
+ {
+ ifstream userStyleDef ( styleInputPath.c_str() );
+ if ( userStyleDef )
+ {
+ ostr << "\n" << styleCommentOpen
+ << " Content of " << styleInputPath
+ << ": " <<styleCommentClose << "\n";
+ string line;
+ while ( getline ( userStyleDef, line ) )
+ {
+ ostr << line << "\n";
+ }
+ userStyleDef.close();
+ }
+ else
+ {
+ ostr << styleCommentOpen
+ << " ERROR: Could not include " << styleInputPath
+ << "." << styleCommentClose << "\n";
+ }
+ }
+ return ostr.str();
+ }
+
+
+ bool CodeGenerator::checkSpecialCmd()
+ {
+
+ //cerr << "token: "<<token<< " index"<< lineIndex << " "<<line [ lineIndex ]<< "sizes: "<<token.size()<<"=="<<line.size()<<endl;
+ string noParseCmd="@highlight";
+ // if single line comment is described with regex, token is equal to line
+ // otherwise start searching after the token, which then consists of comment identifier
+ size_t searchStart= ( token.size() ==line.size() ) ? 0 : lineIndex;
+ size_t cmdPos = line.find ( noParseCmd, searchStart );
+ size_t pos=1;
+ if ( cmdPos!=string::npos )
+ {
+ string res;
+ string replaceVar;
+
+ auto_ptr<Pattern> reDefPattern ( Pattern::compile ( "\\$[-\\w]+" ) );
+ auto_ptr<Matcher> m ( reDefPattern->createMatcher ( line.substr ( noParseCmd.size() +cmdPos ) ) );
+ while ( m.get() && m->findNextMatch() )
+ {
+ res+=line.substr ( noParseCmd.size() +cmdPos + pos ,
+ m->getStartingIndex ( 0 )-pos );
+ replaceVar = m->getGroup ( 0 );
+ if ( replaceVar=="$nl" )
+ {
+ res+="\n";
+ }
+ else if ( replaceVar=="$infile" )
+ {
+ res+= ( inFile.size() ) ? inFile: "stdin";
+ }
+ else if ( replaceVar=="$outfile" )
+ {
+ res+= ( outFile.size() ) ? outFile: "stdout";
+ }
+ else if ( replaceVar=="$title" )
+ {
+ res+= docTitle;
+ }
+ else if ( replaceVar=="$theme"||replaceVar=="$style" )
+ {
+ res+= getStyleName();
+ }
+ else if ( replaceVar=="$font-face" )
+ {
+ res+= getBaseFont();
+ }
+ else if ( replaceVar=="$font-size" )
+ {
+ res+= getBaseFontSize();
+ }
+ else if ( replaceVar=="$encoding" )
+ {
+ res+= encoding;
+ }
+ else if ( replaceVar=="$linenum" )
+ {
+ char numBuf[10];
+ snprintf ( numBuf, sizeof ( numBuf ), "%d", lineNumber );
+ res+= string ( numBuf );
+ }
+ pos=m->getEndingIndex ( 0 );
+ }
+ res+=line.substr ( noParseCmd.size() +cmdPos + pos );
+
+ *out<<res;
+
+ // hide comment line from output
+ token.clear();
+ lineIndex=line.length();
+ getInputChar();
+ lineNumber--;
+ // end hide
+
+ return true; // do not parse line as comment
+ }
+
+ return false; //parse comment as usual
+ }
+
+}
diff --git a/support/highlight/src/core/codegenerator.h b/support/highlight/src/core/codegenerator.h
new file mode 100644
index 0000000000..d5323673a2
--- /dev/null
+++ b/support/highlight/src/core/codegenerator.h
@@ -0,0 +1,729 @@
+/***************************************************************************
+ codegenerator.h - description
+ -------------------
+ begin : Die Jul 9 2002
+ copyright : (C) 2002-2009 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef CODEPARSER_H
+#define CODEPARSER_H
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <iomanip>
+
+#include "languagedefinition.h"
+#include "documentstyle.h"
+#include "ctagsreader.h"
+#include "astyle/astyle.h"
+#include "preformatter.h"
+#include "enums.h"
+#include "stringtools.h"
+
+/// The highlight namespace contains all classes and data structures needed for parsing input data.
+
+namespace highlight
+{
+ /** \brief Regular Expession Information
+
+ This class associates a processing state with a keyword class and the length of the matched token.
+
+ * @author Andre Simon
+ */
+ class ReGroup
+ {
+ public:
+
+ /// Constructor
+ ReGroup() : length ( 0 ), state ( STANDARD ), kwClass ( 0 ), name()
+ {
+ }
+
+ /// Constructor
+ ReGroup ( State s, unsigned int l , unsigned int c, const string&n ) :
+ length ( l ), state ( s ), kwClass ( c ), name(n)
+ {
+ }
+
+ /// Copy Constructor
+ ReGroup ( const ReGroup& other )
+ {
+ length = other.length;
+ state = other.state;
+ kwClass = other.kwClass;
+ name=other.name;
+ }
+
+ /// Operator overloading
+ ReGroup& operator= ( const ReGroup & other )
+ {
+ length = other.length;
+ state = other.state;
+ kwClass = other.kwClass;
+ name=other.name;
+ return *this;
+ }
+
+ ~ReGroup()
+ {
+ }
+
+ unsigned int length; ///< length of the token
+ State state; ///< state of the matched token (keyword, string, etc)
+ unsigned int kwClass; ///< keyword class if state is keyword
+ string name; ///< language name needed to handle embedded languages
+ };
+
+
+ /** \brief Base class for parsing. Works like a finite state machine.
+
+ The virtual class provides source code parsing functionality, based on
+ information stored in language definitions.<br>
+ The derived classes have to define the output format.<br>
+ The colour information is stored in a DocumentStyle instance.<br>
+ Codegenerator is a singleton class.<br>
+ Use getInstance for a singleton class instance. Then call the init* methods
+ and loadLanguage to initialize the parser. Init methods have to be called first.
+ Call generate* methods to get results.
+
+ * @author Andre Simon
+ */
+
+ class CodeGenerator
+ {
+
+ public:
+
+ virtual ~CodeGenerator();
+
+ /**
+ Get appropriate Codegenerator instance (should be used with auto_ptr)
+ \param type Output file type (HTML, XHTML, RTF, LATEX, TEX, ANSI, XTERM256)
+ \return CodeGenerator
+ */
+ static CodeGenerator* getInstance ( OutputType type );
+
+ /**
+ Delete CodeGenerator instance (this is intended for SWIG integration only,
+ in normal C++ code the result of getInstance() should be saved in an auto_ptr)
+ \param CodeGenerator* CodeGenerator instance
+ */
+ static void deleteInstance ( CodeGenerator* inst ) {if ( inst ) delete inst;}
+
+ /**
+ Define colour theme information; needs to be called before using a generate* method.
+ Call this method before loadLanguage().
+ \param themePath Path of style description file
+ \return true if successfull
+ */
+ bool initTheme ( const string& themePath );
+
+ /** initialize source code indentation and reformatting scheme;
+ needs to be called before using a generate* method
+ \param indentScheme Name of indentation scheme
+ \return true if successfull
+ */
+ bool initIndentationScheme ( const string&indentScheme );
+
+ /**
+ Load ctags meta information; needs to be called before using a generate* method
+ \param ctagsPath Path of tags file
+ \return true if successfull
+ */
+ bool initTagInformation ( const string& ctagsPath );
+
+ /** \param langDefPath Absolute path to language definition, may be used multiple times for a generator instance
+ \return LOAD_FAILED: failure,
+ LOAD_NEW: Reload necessary,
+ LOAD_NONE: no reload necessary
+ */
+ LoadResult loadLanguage ( const string& langDefPath );
+
+ /**
+ Generate output file from input file
+ \param inFileName Path of input file (if empty use stdin)
+ \param outFileName Path of output file (if empty use stdout)
+ \return ParseError
+ */
+ ParseError generateFile ( const string &inFileName, const string &outFileName );
+
+ /**
+ Generate output string from input string
+ \param input input code string
+ \return formatted output code
+ */
+ string generateString ( const string &input );
+
+ /**
+ Generate output string from input file
+ \param inFileName file path
+ \return formatted output code
+ */
+ string generateStringFromFile ( const string &inFileName );
+
+ /** Print style definitions to external file or stdout
+ \param outFile Path of external style definition; print to stdout if empty
+ \return true if successfull
+ */
+ bool printExternalStyle ( const string &outFile );
+
+ /** Print index file with all input file names
+ \param fileList List of output file names
+ \param outPath Output path
+ \return true if successfull
+ */
+ virtual bool printIndexFile ( const vector<string> & fileList,
+ const string &outPath );
+
+
+ /** define the preformatting parameters. Preformatting takes place before
+ the optional astyle reformatting and indenting is performed (defined by initIndentationScheme)
+ \param lineWrappingStyle wrapping style (WRAP_DISABLED, WRAP_SIMPLE, WRAP_DEFAULT)
+ \param lineLength max line length
+ \param numberSpaces number of spaces which replace a tab
+ */
+ void setPreformatting ( WrapMode lineWrappingStyle, unsigned int lineLength,int numberSpaces );
+
+ /** \deprecated
+ \return True if document style was found */
+ bool styleFound();
+
+ /** \return True if reformatting of current input is disabled */
+ bool formattingDisabled();
+
+ /** \return True if reformatting of current input is possible */
+ bool formattingIsPossible();
+
+ /** \deprecated
+ \param langDefPath Absolute path to language definition; use loadLanguage instead
+ \return LOAD_FAILED: failure,
+ LOAD_NEW: Reload necessary,
+ LOAD_NONE: no reload necessary
+ */
+ LoadResult initLanguage ( const string& langDefPath ) { return loadLanguage ( langDefPath );}
+
+ /** \return Language definition*/
+ const LanguageDefinition &getLanguage();
+
+ /** output line numbers
+ \param flag true if line numbers should be printed
+ \param startCnt line number starting count
+ */
+ void setPrintLineNumbers ( bool flag, unsigned int startCnt=1 );
+
+ /** \return line number flag */
+ bool getPrintLineNumbers();
+
+ /** output line numbers filled with zeroes
+ \param flag true if zeroes should be printed
+ */
+ void setPrintZeroes ( bool flag );
+
+ /** \return print zeroes flag */
+ bool getPrintZeroes();
+
+ /** omit document header and footer
+ \param flag true if output should be fragmented
+ */
+ void setFragmentCode ( bool flag );
+
+ /** \return fragment flag */
+ bool getFragmentCode();
+
+ /** define line number width
+ \param w width
+ */
+ void setLineNumberWidth ( int w );
+
+ /** \return line number width */
+ int getLineNumberWidth();
+
+ /** check if input is binary or text
+ \param flag true if input should be checked
+ */
+ void setValidateInput ( bool flag );
+
+ /** \return input validation flag */
+ bool getValidateInput();
+
+ /** \return style path */
+ const string& getStyleName();
+
+ /** use this font as base font
+ \param s the font name, e.g. "Courier New"
+ */
+ void setBaseFont ( const string& s );
+
+ /** \return base font */
+ const string getBaseFont() const ;
+
+ /** use this size as base font size
+ \param s the font size, e.g. "12"
+ */
+ void setBaseFontSize ( const string& s );
+
+ /** \return base font size*/
+ const string getBaseFontSize();
+
+ /** tell parser the include style definition in output
+ \param flag true if style should be included
+ */
+ void setIncludeStyle ( bool flag );
+
+
+ /** tell parser to omit trailing newline character
+ \param flag true if no trailing newline should be printed
+ */
+ void disableTrailingNL ( bool flag );
+
+ /** Set style input path
+ \param path path to style input file
+ */
+ void setStyleInputPath ( const string& path );
+
+ /** Set style output path
+ \param path path to style output file
+ */
+ void setStyleOutputPath ( const string& path );
+
+ /** Set encoding (output encoding must match input file)
+ \param encodingName encoding name
+ */
+ void setEncoding ( const string& encodingName );
+
+ /** \return style input file path */
+ const string& getStyleInputPath();
+
+ /** \return style output file path */
+ const string& getStyleOutputPath();
+
+ /** \param title Document title */
+ void setTitle ( const string & title );
+
+ /** \return Document title */
+ string getTitle();
+
+ /** \param cnt maximum number of input lines to be processed */
+ void setMaxInputLineCnt ( unsigned int cnt );
+
+ /** \return true if chosen document style has white background colour */
+ bool hasWhiteBGColour();
+
+ /** \param keyCase Keyword case */
+ void setKeyWordCase ( StringTools::KeywordCase keyCase );
+
+ /** \param lineNo number of line that should be marked
+ \param helpTxt additional help text */
+ void addMarkedLine ( int lineNo, string &helpTxt );
+
+ /** \param delim End of line delimiter (default: NL)
+ */
+ void setEOLDelimiter(char delim);
+
+ /** Define the name of a nested langage which is located at the beginning of input.
+ The opening embedded delimiter is missing, but the closing delimiter must exist.
+ \param langName name of nested language
+ */
+ void setStartingNestedLang(const string &langName);
+
+
+ /** set HTML output anchor flag
+ */
+ virtual void setHTMLAttachAnchors ( bool ) {};
+
+ /** set HTML output ordered list flag
+ */
+ virtual void setHTMLOrderedList ( bool ) {};
+
+ /** set HTML output inline CSS flag
+ */
+ virtual void setHTMLInlineCSS ( bool ) {};
+
+ /** set HTML output enclose pre tag flag
+ */
+ virtual void setHTMLEnclosePreTag ( bool ) {};
+
+ /** set HTML output anchor prefix
+ */
+ virtual void setHTMLAnchorPrefix ( const string& ) {};
+
+ /** set HTML output class name
+ */
+ virtual void setHTMLClassName ( const string& ) {};
+
+ /** set LaTeX replace quotes flag
+ */
+ virtual void setLATEXReplaceQuotes ( bool ) {};
+
+ /** set LaTeX no Babel shorthands flag
+ */
+ virtual void setLATEXNoShorthands ( bool ) {};
+
+ /** set LaTeX pretty Symbols flag
+ */
+ virtual void setLATEXPrettySymbols ( bool ) {};
+
+ /** set RTF page size
+ */
+ virtual void setRTFPageSize ( const string& ) {};
+
+ /** set RTF output character styles flag
+ */
+ virtual void setRTFCharStyles ( bool ) {};
+
+ /** set SVG page size
+ */
+ virtual void setSVGSize ( const string&, const string& ) {};
+
+
+ protected:
+
+ static const unsigned int NUMBER_BUILTIN_STATES; ///< number of token states (without keyword group IDs)
+
+ static const string STY_NAME_STD;
+ static const string STY_NAME_STR;
+ static const string STY_NAME_NUM;
+ static const string STY_NAME_SLC;
+ static const string STY_NAME_COM;
+ static const string STY_NAME_ESC;
+ static const string STY_NAME_DIR;
+ static const string STY_NAME_DST;
+ static const string STY_NAME_LIN;
+ static const string STY_NAME_SYM;
+
+ /** \param type Output type */
+ CodeGenerator ( highlight::OutputType type );
+ CodeGenerator() {};
+
+ /** \param c Character to be masked
+ \return Escape sequence of output format */
+ virtual string maskCharacter ( unsigned char c ) = 0;
+
+ /** \param ss destination stream
+ \param s string */
+ void maskString ( ostream& ss, const string &s ) ;
+
+ /** \param s Symbol string
+ \param searchPos Position where search starts
+ \return Found state (integer value) */
+ State getState ( const string &s, unsigned int searchPos );
+
+ /** Get current line number
+ \return line number */
+ unsigned int getLineNumber();
+
+ vector <string> openTags, ///< list of format delimiters (open new format descriptions)
+ closeTags; ///< list of format delimiters (close format descriptions)
+
+ /** Description of document colour style*/
+ DocumentStyle docStyle;
+
+ /** Language definition*/
+ LanguageDefinition langInfo;
+
+ /** CTags meta information */
+ CTagsReader metaInfo;
+
+ /** Tag for inserting line feeds*/
+ string newLineTag;
+
+ /** String that represents a white space in output */
+ string spacer;
+
+ /** file input*/
+ istream *in;
+
+ /** file output*/
+ ostream *out;
+
+ string maskWsBegin, ///< open whitespace mask
+ maskWsEnd; ///< close whitespace mask
+
+ string styleCommentOpen, ///< open comment delimiter
+ styleCommentClose; ///< close comment delimiter
+
+ string embedBlockOpen, ///< open block delimiter to highlight embedded code
+ embedBlockClose; ///< close block delimiter
+
+ /** Encoding name */
+ string encoding;
+
+ /** document title */
+ string docTitle;
+
+ string inFile, ///< input file name
+ outFile; ///< output file name
+
+ /** Test if maskWsBegin and maskWsEnd should be applied */
+ bool maskWs;
+
+ /** Test if whitespace sould always be separated from enclosing tokens */
+ bool excludeWs;
+
+ /** Test if header and footer should be omitted */
+ bool fragmentOutput;
+
+ /** Test if line numbers should be printed */
+ bool showLineNumbers;
+
+ /** Test if leading spyce of line number should be filled with zeroes*/
+ bool lineNumberFillZeroes;
+
+ /** Flag to test if newlines should be printed */
+ bool printNewLines;
+
+ /** The base font to use */
+ string baseFont ;
+
+ /** The base font size to use */
+ string baseFontSize ;
+
+ /** Current line of input file*/
+ string line;
+
+ /** Current line number */
+ unsigned int lineNumber;
+
+ /**output line number count start */
+ int lineNumberOffset;
+
+ /** Current state*/
+ State currentState;
+
+ /** keyword class id, used to apply the corresponding keyword style*/
+ unsigned int currentKeywordClass;
+
+ /** Processes origin state */
+ void processRootState();
+
+ /** \return line break sequence */
+ virtual string getNewLine();
+
+ /**
+ \param s current state
+ \param kwClassID keyword class (has to be set when s=KEYWORD)
+ \return Index of style tag corresponding to the states
+ */
+ unsigned int getStyleID ( State s, unsigned int kwClassID = 0 );
+
+ /** \return line index */
+ unsigned int getLineIndex();
+
+ /** print all remaining white space*/
+ void flushWs();
+
+ /** \return Content of user defined input style */
+ string readUserStyleDef();
+
+ /** \return Style definition of the chosen output format */
+ virtual string getStyleDefinition() {return "";};
+
+ /** \return true id encoding is defined */
+ bool encodingDefined() {return StringTools::change_case ( encoding ) !="none";}
+
+ /** contains white space, which will be printed after a closing tag */
+ string wsBuffer;
+
+ /** Flag to test if style definition should be included in output document */
+ bool includeStyleDef;
+
+ /** map which saves all lines that should be highlghted */
+ map <int, string> markLines;
+
+ /** Class for line wrapping and tab replacement*/
+ PreFormatter preFormatter;
+
+ private:
+
+ CodeGenerator ( const CodeGenerator& ) {}
+
+ CodeGenerator& operator= ( CodeGenerator& ) { return *this;}
+
+ /** Insert line number at the beginning of current output line */
+ virtual void insertLineNumber ( bool insertNewLine=true );
+
+ /** Prints document footer
+ @return footer */
+ virtual string getFooter() = 0;
+
+ /** Prints document body*/
+ virtual void printBody() = 0;
+
+ /** Prints document header
+ @return header
+ */
+ virtual string getHeader() = 0;
+
+ /** initialize tags in specific format according to colouring information provided in DucumentStyle */
+ virtual void initOutputTags() = 0;
+
+ /** \param keyword group id
+ \return open tag */
+ virtual string getKeywordOpenTag ( unsigned int ) = 0;
+
+ /** \param keyword group id
+ \return close tag */
+ virtual string getKeywordCloseTag ( unsigned int ) = 0;
+
+ /** return open tag to include ctags meta information
+ \param info tag information of current token
+ \return opening tag
+ */
+ virtual string getMetaInfoOpenTag ( const TagInfo& info ) {return "";}
+
+ /** return close tag of meta information
+ \return closing tag
+ */
+ virtual string getMetaInfoCloseTag() {return "";}
+
+ /** open a new tag, set current state to s*/
+ void openTag ( State s );
+
+ /** close opened tag, clear current state */
+ void closeTag ( State s );
+
+ /** close Keyword tag of corresponding style ID */
+ void closeKWTag ( unsigned int styleID );
+
+ /** open Keyword tag of corresponding style ID */
+ void openKWTag ( unsigned int styleID );
+
+
+
+ /*void closeTag ( unsigned int styleID );
+
+ void openTag ( unsigned int styleID );*/
+
+ /// path to style definition file
+ string themePath;
+
+ /// path to host language definition
+ string hostLangDefPath;
+
+ /// path to embedded language definition
+ string embedLangDefPath;
+
+ /// name of nested language which starts the input (ie opening delim missing, but closing delim exists)
+ string embedLangStart;
+
+ /// contains current position in line
+ unsigned int lineIndex;
+
+ /// width of line numbering coloumn
+ unsigned int lineNumberWidth;
+
+ /**maximum count of input lines to be processed*/
+ unsigned int maxLineCnt;
+
+ /**last character of the last line*/
+ unsigned char terminatingChar;
+
+ /** Class for reformatting */
+ astyle::ASFormatter *formatter;
+
+ /** Flag to test if formatting is enabled with current input document*/
+ bool formattingEnabled;
+
+ /** Flag to test if formatting is possible with current input document*/
+ bool formattingPossible;
+
+ /** Flag to test if input should be validated (binary or text) */
+ bool validateInput;
+
+ /** Flag to test if ctags information is available */
+ bool tagsEnabled;
+
+ /** Flag to test if trailing newline should be printed */
+ bool noTrailingNewLine;
+
+ /** flag which determines keyword output (unchangeed, uppercase, lowercase)*/
+ StringTools::KeywordCase keywordCase;
+
+ /** contains the current token*/
+ string token;
+
+ string styleInputPath, ///< style input file path
+ styleOutputPath; ///< style output file path
+
+ /** end-of-line delimiter*/
+ char eolDelimiter;
+
+ /** Resets parser to origin state, call this after every file conversion */
+ void reset();
+
+ /** read new line from in stream */
+ bool readNewLine ( string &newLine );
+
+ /** return next character from in stream */
+ unsigned char getInputChar();
+
+ /** output file type */
+ OutputType outputType;
+
+ /** return new state */
+ State getCurrentState ();
+
+ /* Methods that represent a parsing state */
+ bool processKeywordState ( State myState ); ///< process keywords
+ bool processNumberState() ; ///< process numbers
+ bool processMultiLineCommentState(); ///< process multi line comments
+ bool processSingleLineCommentState(); ///< process single line comments
+ bool processStringState ( State oldState ); ///< process strings
+ bool processEscapeCharState(); ///< process escape characters
+ bool processDirectiveState(); ///< process directives
+ bool processTagState(); ///< process tags
+ bool processSymbolState(); ///< process symbols
+ void processWsState(); ///< process whitespace
+ bool processSyntaxChangeState(State myState ); ///< process syntax change of embedded languages
+
+ /** print escaped token and clears it
+ \param addMetaInfo set true if token may have meta information
+ \param flushWhiteSpace set true if white space should be flushed
+ \param tcase keyword case
+ */
+ void printMaskedToken ( bool addMetaInfo = false, bool flushWhiteSpace = true,
+ StringTools::KeywordCase tcase = StringTools::CASE_UNCHANGED );
+
+ /** look for special commands in comments
+ \return true if command was found
+ */
+ bool checkSpecialCmd();
+
+ /** association of matched regexes and the corresponding keyword class ids*/
+ map <int, ReGroup> regexGroups;
+
+ /** test for regular expressions
+ \param line current input line*/
+ void matchRegex ( const string &line );
+
+ /** \return true if input is no binary stream */
+ bool validateInputStream();
+
+ void loadEmbeddedLang(const string&embedLangDefPath);
+
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/configurationreader.cpp b/support/highlight/src/core/configurationreader.cpp
new file mode 100644
index 0000000000..49b3cca2d4
--- /dev/null
+++ b/support/highlight/src/core/configurationreader.cpp
@@ -0,0 +1,112 @@
+/***************************************************************************
+ configurationreader.cpp - description
+ -------------------
+ begin : Son Nov 10 2002
+ copyright : (C) 2002 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "configurationreader.h"
+
+#include <string>
+#include <sstream>
+#include <map>
+#include <iostream>
+#include <fstream>
+#include <vector>
+
+#include "stringtools.h"
+
+using namespace std;
+
+ConfigurationReader::ConfigurationReader ( const string & configuration_path )
+{
+ ifstream in ( configuration_path.c_str() );
+ fileFound=in;
+ if ( fileFound )
+ {
+ string line;
+ line.reserve ( 500 );
+ size_t lineBegin;
+ size_t delimPos;
+ string paramName;
+ char suffix[10];
+ int i=0;
+
+ while ( getline ( in, line ) )
+ {
+ lineBegin=line.find_first_not_of ( "\t " );
+ if ( ( line.size() >2 ) && ( lineBegin!=string::npos )
+ && ( line.at ( lineBegin ) !='#' ) ) //comment?
+ {
+ if ( line[lineBegin]=='$' ) // new parameter?
+ {
+ delimPos=line.find ( "=",lineBegin )-1;
+ if ( delimPos!=string::npos )
+ {
+ paramName=StringTools::trimRight (
+ StringTools::change_case ( line.substr ( lineBegin+1, delimPos ) ) );
+ // if parameter already exists, make it unique
+ if ( parameterMap.count ( paramName ) )
+ {
+ snprintf ( suffix, sizeof ( suffix ), "#%05d", ++i );
+ paramName+=suffix;
+ }
+ parameterNames.push_back ( paramName );
+ parameterMap[paramName] = line.substr ( delimPos+2, line.length() );
+ }
+ }
+ else
+ {
+ parameterMap[paramName]+= ( " "+line );
+ }
+ }
+ }
+ in.close();
+ }
+}
+
+ConfigurationReader::~ConfigurationReader()
+{
+}
+
+bool ConfigurationReader::found()
+{
+ return fileFound;
+}
+
+string &ConfigurationReader::getParameter ( const string & paramName )
+{
+ return parameterMap[paramName] ;
+}
+
+const char* ConfigurationReader::getCParameter ( const string & paramName )
+{
+ return parameterMap[paramName].c_str() ;
+}
+
+vector<string> &ConfigurationReader::getParameterNames()
+{
+ return parameterNames;
+}
+
+
diff --git a/support/highlight/src/core/configurationreader.h b/support/highlight/src/core/configurationreader.h
new file mode 100644
index 0000000000..7755081c12
--- /dev/null
+++ b/support/highlight/src/core/configurationreader.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ configurationreader.h - description
+ -------------------
+ begin : Son Nov 10 2002
+ copyright : (C) 2002 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef CONFIGURATIONREADER_H
+#define CONFIGURATIONREADER_H
+
+#include <string>
+#include <map>
+#include <vector>
+
+using namespace std;
+
+/** Maps parameter keys to values*/
+typedef map<string, string> ParameterMap;
+
+
+/** \brief Class to handle ASCII config files
+
+ Configuration file format:<br>
+ $ParamName=ParamValue<br>
+ ParamValue may be splittet over multiple lines<br>
+ ParamName is not case sensitive<br>
+ Comments start with # as the first character of a line
+
+ **/
+
+class ConfigurationReader
+{
+ public:
+ /** Constructor
+ \param configuration_path Path to configuration file
+ */
+ ConfigurationReader ( const string & configuration_path );
+ ~ConfigurationReader();
+
+ /** \param paramName Name of parameter
+ \return Value of parameter */
+ string &getParameter ( const string & paramName );
+
+ /** \param paramName Name of parameter
+ \return Value of parameter */
+ const char* getCParameter ( const string & paramName );
+
+ /** \return True if config file exists */
+ bool found();
+
+ /** \return List of parameter names */
+ vector<string> &getParameterNames();
+
+ private:
+ ParameterMap parameterMap;
+ bool fileFound;
+ vector<string> parameterNames;
+};
+
+#endif
diff --git a/support/highlight/src/core/ctagsreader.cpp b/support/highlight/src/core/ctagsreader.cpp
new file mode 100644
index 0000000000..acfa35e649
--- /dev/null
+++ b/support/highlight/src/core/ctagsreader.cpp
@@ -0,0 +1,99 @@
+/***************************************************************************
+ ctagsreader.h - description
+ -------------------
+ begin : Tue Oct 21 2008
+ copyright : (C) 2008 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "ctagsreader.h"
+
+
+string TagInfo::getKind() const
+{
+ if ( kind.empty() ) return "";
+ switch ( kind[0] )
+ {
+ case 'c': return "class";
+ case 'd': return "define";
+ case 'e': return "enumerator";
+ case 'f': return "function";
+ case 'F': return "file";
+ case 'g': return "enumeration name";
+ case 'm': return "member";
+ case 'n': return "namespace";
+ case 'p': return "function prototype";
+ case 's': return "structure name";
+ case 't': return "typedef";
+ case 'u': return "union name";
+ case 'v': return "variable";
+ default: return "";
+ }
+}
+
+bool CTagsReader::load ( const string & ctags_path )
+{
+ ifstream in ( ctags_path.c_str() );
+ if ( in )
+ {
+ string line;
+ string tagname,
+ tagfile,
+ dummy1,
+ dummy2,
+ kind,
+ name_space,
+ file;
+ TagInfo info;
+ line.reserve ( 250 );
+ while ( getline ( in, line ) && line.size() )
+ {
+ if ( line[0]=='!' )
+ {
+ continue;
+ }
+
+ istringstream tagStream ( line );
+ if ( !getline ( tagStream, tagname, '\t' ) ) continue;
+ if ( !getline ( tagStream, tagfile, '\t' ) ) continue;
+ if ( !getline ( tagStream, dummy1, '\t' ) ) continue;
+ if ( !getline ( tagStream, dummy2, '\t' ) ) continue;
+ if (dummy2.empty()) {
+ while (dummy2.empty()) {
+ if ( !getline ( tagStream, dummy2, '\t' ) ) continue;
+ }
+ }
+ if ( !getline ( tagStream, kind, '\t' ) ) continue;
+ name_space.clear(); file.clear();
+ getline ( tagStream, name_space, '\t' );
+
+ info.file=tagfile;
+ info.kind=kind;
+ info.name_space=name_space;
+ //info.tag_exists=true;
+ tags[tagname] = info;
+ }
+ in.close();
+ return true;
+ }
+ return false;
+}
diff --git a/support/highlight/src/core/ctagsreader.h b/support/highlight/src/core/ctagsreader.h
new file mode 100644
index 0000000000..3686242dda
--- /dev/null
+++ b/support/highlight/src/core/ctagsreader.h
@@ -0,0 +1,104 @@
+/***************************************************************************
+ ctagsreader.h - description
+ -------------------
+ begin : Tue Oct 21 2008
+ copyright : (C) 2008 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef CTAGSREADER_H
+#define CTAGSREADER_H
+
+#include <string>
+#include <sstream>
+#include <map>
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+/** TagInfo contains information about a ctags tag */
+class TagInfo
+{
+ public:
+ TagInfo() {};
+ string getKind() const;
+ string file, kind, name_space;
+
+};
+
+/** Maps parameter keys to values*/
+typedef map<string, TagInfo> TagsMap;
+
+class CTagsReader
+{
+ public:
+
+ CTagsReader() {};
+ ~CTagsReader() {};
+
+ /** load ctags file
+ \param ctags_path Path to ctags file
+ \return true if successfull
+ */
+ bool load ( const string & ctags_path );
+
+ /** test if tag infoation exists
+ \param tagname tag ot highlight token
+ \return true if tag information exists
+ */
+ bool tagExists ( const string& tagname )
+ {
+ return tags.count ( tagname ) >0;
+ }
+
+ /** return tag info, call tagExists first to avoid growing map
+ \param tagname tag ot highlight token
+ \return tag info
+ */
+ TagInfo getTagInfo ( const string &tagname )
+ {
+ return tags[tagname];
+ }
+
+ private:
+
+ TagsMap tags;
+};
+
+/*
+ c class name
+ d define (from #define XXX)
+ e enumerator
+ f function or method name
+ F file name
+ g enumeration name
+ m member (of structure or class data)
+ p function prototype
+ s structure name
+ t typedef
+ u union name
+ v variable
+
+*/
+
+#endif
diff --git a/support/highlight/src/core/datadir.cpp b/support/highlight/src/core/datadir.cpp
new file mode 100644
index 0000000000..faa929301a
--- /dev/null
+++ b/support/highlight/src/core/datadir.cpp
@@ -0,0 +1,181 @@
+/***************************************************************************
+ dataDir.cpp - description
+ -------------------
+ begin : Sam March 1 2003
+ copyright : (C) 2003 by André Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <string>
+#include <fstream>
+#include <vector>
+#include "platform_fs.h"
+
+#include "datadir.h"
+
+using namespace std;
+
+string DataDir::LSB_DATA_DIR="/usr/share/highlight/";
+string DataDir::LSB_CFG_DIR="/etc/highlight/";
+string DataDir::LSB_DOC_DIR="/usr/share/doc/highlight/";
+
+
+bool DataDir::searchDataDir ( const string &userDefinedDir )
+{
+
+#ifndef _WIN32
+ bool found = false;
+
+ vector <string> possibleDirs;
+ if ( !userDefinedDir.empty() ) possibleDirs.push_back ( userDefinedDir );
+// if (!additionalDataDir.empty()) possibleDirs.push_back(additionalDataDir);
+#ifdef HL_DATA_DIR
+ possibleDirs.push_back ( HL_DATA_DIR );
+#endif
+ possibleDirs.push_back ( LSB_DATA_DIR );
+
+ for ( unsigned int i=0;i<possibleDirs.size();i++ )
+ {
+ if ( fileExists ( possibleDirs[i] ) )
+ {
+ dataDir=possibleDirs[i];
+ found = true; break;
+ }
+ }
+ return found;
+#else
+ dataDir=userDefinedDir;
+ return true;
+#endif
+}
+
+DataDir::DataDir()
+{
+}
+
+void DataDir::setAdditionalDataDir ( const string& dir )
+{
+ additionalDataDir=dir;
+}
+void DataDir::setAdditionalConfDir ( const string& dir )
+{
+ additionalConfDir=dir;
+}
+
+const string & DataDir::getAdditionalDataDir()
+{
+ return additionalDataDir;
+}
+
+const string & DataDir::getAdditionalConfDir()
+{
+ return additionalConfDir;
+}
+
+const string &DataDir::getDir()
+{
+ return dataDir;
+}
+
+const string DataDir::getLangPath ( const string & file, bool forceDefault )
+{
+ if ( !forceDefault && !additionalDataDir.empty() )
+ {
+ string path=getAdditionalLangDefDir() +file;
+ if ( fileExists ( path ) )
+ {
+ return path;
+ }
+ }
+ return dataDir+"langDefs"+Platform::pathSeparator+file;
+}
+
+const string DataDir::getThemePath ( const string & file, bool forceDefault )
+{
+ if ( !forceDefault && !additionalDataDir.empty() )
+ {
+ string path=getAdditionalThemeDir() +file;
+ if ( fileExists ( path ) )
+ {
+ return path;
+ }
+ }
+ return dataDir+"themes"+Platform::pathSeparator+file;
+}
+
+const string DataDir::getConfDir ( bool forceDefault )
+{
+ if ( !forceDefault && !additionalConfDir.empty() )
+ {
+ return additionalConfDir;
+ }
+#ifndef _WIN32
+#ifdef HL_CONFIG_DIR
+ return HL_CONFIG_DIR;
+#else
+ return LSB_CFG_DIR;
+#endif
+#else
+ return getDir();
+#endif
+}
+
+const string DataDir::getAdditionalLangDefDir()
+{
+ return additionalDataDir+"langDefs"+Platform::pathSeparator;
+}
+
+const string DataDir::getAdditionalThemeDir()
+{
+ return additionalDataDir+"themes"+Platform::pathSeparator;
+}
+
+const string DataDir::getI18nDir()
+{
+ return dataDir+"gui_files"+Platform::pathSeparator+"i18n"+Platform::pathSeparator;
+}
+
+const string DataDir::getExtDir()
+{
+ return dataDir+"gui_files"+Platform::pathSeparator+"ext"+Platform::pathSeparator;
+}
+
+const string DataDir::getDocDir()
+{
+#ifndef _WIN32
+#ifdef HL_DOC_DIR
+ return HL_CONFIG_DIR;
+#else
+ return LSB_DOC_DIR;
+#endif
+#else
+ return getDir();
+#endif
+}
+
+bool DataDir::fileExists ( const string&f )
+{
+ ifstream file ( f.c_str() );
+ bool exists=!file.fail();
+ file.close();
+ return exists;
+}
diff --git a/support/highlight/src/core/datadir.h b/support/highlight/src/core/datadir.h
new file mode 100644
index 0000000000..1c180156e2
--- /dev/null
+++ b/support/highlight/src/core/datadir.h
@@ -0,0 +1,108 @@
+/***************************************************************************
+ datadir.h - description
+ -------------------
+ begin : Sam March 1 2003
+ copyright : (C) 2003 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef DATADIR_H
+#define DATADIR_H
+
+using namespace std;
+
+/** \brief Manages access to installation directories.
+
+ Apart from the standard installation directory, one can define additional
+ search paths. If the additonal paths do not exist, the default paths are
+ returned.
+ **/
+
+class DataDir
+{
+ string dataDir;
+ string additionalDataDir;
+ string additionalConfDir;
+ bool fileExists ( const string& );
+
+ public:
+
+ DataDir();
+
+ static string LSB_DATA_DIR;
+ static string LSB_CFG_DIR;
+ static string LSB_DOC_DIR;
+
+ /** search for a valid installation directory
+ \param userDefinedDir Directory defined by user
+ \return True if directory was found */
+ bool searchDataDir ( const string &userDefinedDir );
+
+ /** add another installation directory, which is added to search path
+ \param dir Directory defined by user */
+ void setAdditionalDataDir ( const string& dir );
+
+ /** add another installation directory, which is added to search path
+ \param dir Directory defined by user */
+ void setAdditionalConfDir ( const string& dir );
+
+ /** \return data Directory defined by user */
+ const string & getAdditionalDataDir();
+
+ /** \return data Directory defined by user */
+ const string & getAdditionalConfDir();
+
+ /** \return Data installation directory */
+ const string & getDir() ;
+
+ /** \param file filename
+ \param forceDefault set tue if additional directory should be ignored
+ \return Location of languafe definitions */
+ const string getLangPath ( const string & file="", bool forceDefault=false ) ;
+
+ /** \param file filename
+ \param forceDefault set tue if additional directory should be ignored
+ \return Location of themes */
+ const string getThemePath ( const string & file="", bool forceDefault=false ) ;
+
+ /** \return User defined location of languafe definitions */
+ const string getAdditionalLangDefDir() ;
+
+ /** \return User defined location of themes */
+ const string getAdditionalThemeDir() ;
+
+ /** \param forceDefault set tue if additional directory should be ignored
+ \return Location of configuration files */
+ const string getConfDir ( bool forceDefault=false ) ;
+
+ /** \return Location of GUI menu translation files */
+ const string getI18nDir();
+
+ /** \return Location of GUI file extension filter files */
+ const string getExtDir();
+
+ /** \return Location of documentation (README) files (GUI) */
+ const string getDocDir();
+
+};
+
+#endif
diff --git a/support/highlight/src/core/documentstyle.cpp b/support/highlight/src/core/documentstyle.cpp
new file mode 100644
index 0000000000..9c5f7307d5
--- /dev/null
+++ b/support/highlight/src/core/documentstyle.cpp
@@ -0,0 +1,168 @@
+/***************************************************************************
+ documentstyle.cpp - description
+ -------------------
+ begin : Son Nov 10 2002
+ copyright : (C) 2002 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "documentstyle.h"
+#include "stringtools.h"
+
+namespace highlight
+{
+
+ DocumentStyle::DocumentStyle ( const string &styleDefinitionFile )
+ {
+ fileFound=load ( styleDefinitionFile );
+ }
+ DocumentStyle::DocumentStyle() :fileFound ( false )
+ {}
+
+ bool DocumentStyle::load ( const string &styleDefinitionPath )
+ {
+ ConfigurationReader styleConfig ( styleDefinitionPath );
+ fileFound = false;
+ if ( styleConfig.found() )
+ {
+ fontsize = styleConfig.getParameter ( "fontsize" );
+ bgColour.setRGB ( styleConfig.getParameter ( "bgcolour" ) );
+ defaultElem.set ( styleConfig.getParameter ( "defaultcolour" ) );
+ comment.set ( styleConfig.getParameter ( "comment" ) );
+ directive.set ( styleConfig.getParameter ( "directive" ) );
+ str.set ( styleConfig.getParameter ( "string" ) );
+ escapeChar.set ( styleConfig.getParameter ( "escapechar" ) );
+ number.set ( styleConfig.getParameter ( "number" ) );
+ dstr.set ( styleConfig.getParameter ( "string-directive" ) );
+ line.set ( styleConfig.getParameter ( "line" ) );
+ symbol.set ( styleConfig.getParameter ( "symbol" ) );
+ markLineColour.setRGB ( styleConfig.getParameter ( "mark-line" ) );
+
+ string tmpstr;
+ // TODO: Remove this check as soon as all themes have a sl-comment attribute
+ tmpstr=styleConfig.getParameter ( "sl-comment" );
+ if ( tmpstr.empty() )
+ {
+ tmpstr=styleConfig.getParameter ( "comment" );
+ }
+ slcomment.set ( tmpstr );
+
+ string paramVal;
+ vector<string> paramNames=styleConfig.getParameterNames();
+
+ //collect keyword groups, save corresponding style definition
+ for ( unsigned int i=0;i<paramNames.size();i++ )
+ {
+ paramVal=paramNames[i];
+ if ( paramVal.find ( "kw-group" ) != string::npos)
+ {
+ keywordStyles.insert ( make_pair ( StringTools::getParantheseVal ( paramVal ),
+ ElementStyle ( styleConfig.getParameter ( paramVal ) ) ) );
+ }
+ }
+ fileFound = true;
+ }
+ return fileFound;
+ }
+
+ DocumentStyle::~DocumentStyle()
+ {
+ }
+
+ string DocumentStyle::getFontSize() const
+ {
+ return fontsize;
+ }
+ Colour DocumentStyle::getBgColour() const
+ {
+ return bgColour;
+ }
+ Colour DocumentStyle::getMarkLineColour() const
+ {
+ return markLineColour;
+ }
+ ElementStyle DocumentStyle::getDefaultStyle() const
+ {
+ return defaultElem;
+ }
+ ElementStyle DocumentStyle::getCommentStyle() const
+ {
+ return comment;
+ }
+ ElementStyle DocumentStyle::getSingleLineCommentStyle() const
+ {
+ return slcomment;
+ }
+ ElementStyle DocumentStyle::getStringStyle() const
+ {
+ return str;
+ }
+ ElementStyle DocumentStyle::getDirectiveStringStyle() const
+ {
+ return dstr;
+ }
+ ElementStyle DocumentStyle::getEscapeCharStyle() const
+ {
+ return escapeChar;
+ }
+ ElementStyle DocumentStyle::getNumberStyle() const
+ {
+ return number;
+ }
+ ElementStyle DocumentStyle::getDirectiveStyle() const
+ {
+ return directive;
+ }
+ ElementStyle DocumentStyle::getLineStyle() const
+ {
+ return line;
+ }
+ ElementStyle DocumentStyle::getSymbolStyle() const
+ {
+ return symbol;
+ }
+ bool DocumentStyle::found () const
+ {
+ return fileFound;
+ }
+ ElementStyle DocumentStyle::getKeywordStyle ( const string &className )
+ {
+ if ( !keywordStyles.count ( className ) ) return defaultElem;
+ return keywordStyles[className];
+ }
+
+ vector <string> DocumentStyle::getClassNames() const
+ {
+ vector <string> kwClassNames;
+ for ( KSIterator iter = keywordStyles.begin(); iter != keywordStyles.end(); iter++ )
+ {
+ kwClassNames.push_back ( ( *iter ).first );
+ }
+ return kwClassNames;
+ }
+
+ KeywordStyles DocumentStyle::getKeywordStyles() const
+ {
+ return keywordStyles;
+ }
+
+}
diff --git a/support/highlight/src/core/documentstyle.h b/support/highlight/src/core/documentstyle.h
new file mode 100644
index 0000000000..46d8aa5e7a
--- /dev/null
+++ b/support/highlight/src/core/documentstyle.h
@@ -0,0 +1,138 @@
+/***************************************************************************
+ documentstyle.h - description
+ -------------------
+ begin : Son Nov 10 2002
+ copyright : (C) 2002-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef DOCUMENTSTYLE_H
+#define DOCUMENTSTYLE_H
+
+#include <string>
+#include "configurationreader.h"
+#include "elementstyle.h"
+#include "stylecolour.h"
+
+using namespace std;
+
+namespace highlight
+{
+
+ /** maps keyword class names and the corresponding formatting information*/
+ typedef map <string, ElementStyle> KeywordStyles;
+
+ /** iterator for keyword styles*/
+ typedef KeywordStyles::const_iterator KSIterator;
+
+ /** \brief Contains information about document formatting properties.
+ * @author Andre Simon
+ */
+
+ class DocumentStyle
+ {
+ private:
+ ElementStyle comment, slcomment, str, dstr,
+ escapeChar, number, directive, line, symbol;
+ ElementStyle defaultElem;
+ Colour bgColour;
+ Colour markLineColour;
+
+ string fontsize;
+ bool fileFound;
+
+ KeywordStyles keywordStyles;
+
+ public:
+ /** Constructor
+ \param styleDefinitionPath Style definition path */
+ DocumentStyle ( const string & styleDefinitionPath );
+
+ /** Constructor */
+ DocumentStyle();
+ ~DocumentStyle();
+
+ /** load style definition
+ \param styleDefinitionFile Style definition path
+ \return True if successfull */
+ bool load ( const string & styleDefinitionFile );
+
+ /** \return class names defined in the theme file */
+ vector <string> getClassNames() const;
+
+ /** \return keyword styles */
+ KeywordStyles getKeywordStyles() const;
+
+ /** \return Font size */
+ string getFontSize() const;
+
+ /** \return Background colour*/
+ Colour getBgColour() const;
+
+ /** \return Mark line colour*/
+ Colour getMarkLineColour() const;
+
+ /** \return Style of default (unrecognized) strings */
+ ElementStyle getDefaultStyle() const;
+
+ /** \return Comment style*/
+ ElementStyle getCommentStyle() const;
+
+ /** \return Single line comment style*/
+ ElementStyle getSingleLineCommentStyle() const;
+
+ /** \return String style*/
+ ElementStyle getStringStyle() const;
+
+ /** \return Directive line string style*/
+ ElementStyle getDirectiveStringStyle() const;
+
+ /** \return Escape character style*/
+ ElementStyle getEscapeCharStyle() const;
+
+ /** \return Number style*/
+ ElementStyle getNumberStyle() const;
+
+ /** \return Directive style*/
+ ElementStyle getDirectiveStyle() const;
+
+ /** \return Type style*/
+ ElementStyle getTypeStyle() const;
+
+ /** \return Line number style*/
+ ElementStyle getLineStyle() const;
+
+ /** \return Bracket style*/
+ ElementStyle getSymbolStyle() const;
+
+ /** \param className Name of keyword class (eg kwa, kwb, .., kwd)
+ \return keyword style of the given className
+ */
+ ElementStyle getKeywordStyle ( const string &className ) ;
+
+ /** \return True if language definition was found */
+ bool found() const ;
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/elementstyle.cpp b/support/highlight/src/core/elementstyle.cpp
new file mode 100644
index 0000000000..b1a5e408b7
--- /dev/null
+++ b/support/highlight/src/core/elementstyle.cpp
@@ -0,0 +1,111 @@
+/***************************************************************************
+ elementstyle.cpp - description
+ -------------------
+ begin : Son Nov 10 2002
+ copyright : (C) 2002-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <sstream>
+#include "elementstyle.h"
+
+namespace highlight
+{
+
+ ElementStyle::ElementStyle (const Colour &col, bool b, bool i, bool u )
+ : colour ( col ) , bold ( b ), italic ( i ), underline ( u )
+ {}
+
+ ElementStyle:: ElementStyle ( const string & elementStyleString )
+ : bold ( false ), italic ( false ), underline ( false )
+ {
+ set ( elementStyleString );
+ }
+
+ ElementStyle::ElementStyle()
+ : bold ( false ), italic ( false ), underline ( false )
+ {}
+
+ void ElementStyle::set ( const string & elementStyleString )
+ {
+ istringstream valueStream ( elementStyleString );
+ string r, g, b, attr;
+
+ char c='\0';
+ valueStream >> c;
+
+ if ( c=='#' )
+ {
+ string htmlNotation;
+ valueStream >> htmlNotation;
+ if ( htmlNotation.size() < 6 ) return;
+ r = htmlNotation.substr ( 0, 2 );
+ g = htmlNotation.substr ( 2, 2 );
+ b = htmlNotation.substr ( 4, 2 );
+ }
+ else
+ {
+ valueStream.putback ( c );
+ valueStream >> r;
+ valueStream >> g;
+ valueStream >> b;
+ }
+
+ colour.setRed ( r );
+ colour.setGreen ( g );
+ colour.setBlue ( b );
+ while ( valueStream >> attr )
+ {
+ if ( attr=="italic" )
+ {
+ italic = true;
+ }
+ else if ( attr=="bold" )
+ {
+ bold = true;
+ }
+ else if ( attr=="underline" )
+ {
+ underline = true;
+ }
+ }
+ }
+
+ ElementStyle::~ElementStyle()
+ {}
+
+ bool ElementStyle::isItalic() const
+ {
+ return italic;
+ }
+ bool ElementStyle::isBold() const
+ {
+ return bold;
+ }
+ bool ElementStyle::isUnderline() const
+ {
+ return underline;
+ }
+ Colour ElementStyle::getColour() const
+ {
+ return colour;
+ }
+
+}
diff --git a/support/highlight/src/core/elementstyle.h b/support/highlight/src/core/elementstyle.h
new file mode 100644
index 0000000000..45a7c5cc44
--- /dev/null
+++ b/support/highlight/src/core/elementstyle.h
@@ -0,0 +1,121 @@
+/***************************************************************************
+ elementstyle.h - description
+ -------------------
+ begin : Son Nov 10 2002
+ copyright : (C) 2002-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef ELEMENTSTYLE_H
+#define ELEMENTSTYLE_H
+
+#include "stylecolour.h"
+
+using namespace std;
+
+namespace highlight
+{
+
+ /** \brief The class stores the basic text formatting properties.
+
+ * @author Andre Simon
+ */
+
+ class ElementStyle
+ {
+ public:
+
+ /** Constructor
+ \param col Style colour
+ \param b Bold flag
+ \param i Italic flag
+ \param u Underline flag */
+ ElementStyle ( const Colour& col, bool b, bool i, bool u );
+
+ /** Constuctor
+ \param elementStyleString String with formatting information (eg "00 aa ff bold") */
+ ElementStyle ( const string & elementStyleString );
+
+ /** Constuctor */
+ ElementStyle();
+
+ /**copy constructor */
+ ElementStyle ( const ElementStyle &other )
+ {
+ colour = other.getColour();
+ bold = other.isBold();
+ italic = other.isItalic();
+ underline = other.isUnderline();
+ }
+
+ /** operator overloading */
+ ElementStyle& operator= ( const ElementStyle &other )
+ {
+ colour = other.getColour();
+ bold = other.isBold();
+ italic = other.isItalic();
+ underline = other.isUnderline();
+ return *this;
+ }
+
+ ~ElementStyle();
+
+ /** initialize object
+ \param elementStyleString String which contains formatting attributes
+ (Format: "color attr" where
+ color can be HTML hex notation or a hex RGB tuple (ie "#2244ff" or "22 44 ff")
+ attr can be a combination of "italic, "bold" and "underline")
+ */
+ void set ( const string & elementStyleString );
+
+ /** \return True if italic */
+ bool isItalic() const;
+
+ /** \return True if bold */
+ bool isBold() const;
+
+ /** \return True if underline */
+ bool isUnderline() const;
+
+ /** \param b set italic flag */
+ void setItalic ( bool b ) {italic = b;}
+
+ /** \param b set bold flag */
+ void setBold ( bool b ) { bold = b; }
+
+ /** \param b set underline flag */
+ void setUnderline ( bool b ) {underline = b; }
+
+ /** \return Element colour */
+ Colour getColour() const;
+
+ /** \param col colour of this element */
+ void setColour (const Colour& col ) {colour = col;}
+
+ private:
+ Colour colour;
+ bool bold, italic, underline;
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/enums.h b/support/highlight/src/core/enums.h
new file mode 100644
index 0000000000..0b5609dc0d
--- /dev/null
+++ b/support/highlight/src/core/enums.h
@@ -0,0 +1,109 @@
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef ENUMS_H
+#define ENUMS_H
+
+namespace highlight
+{
+
+ /** states which may occour during input file parsing
+ TODO Clean up!
+ */
+ enum State
+ {
+ STANDARD=0,
+ STRING,
+ NUMBER,
+ SL_COMMENT,
+ ML_COMMENT,
+ ESC_CHAR,
+ DIRECTIVE,
+ DIRECTIVE_STRING,
+ LINENUMBER,
+ SYMBOL,
+
+ // don't use constants > 10 as array indices!
+ KEYWORD,
+ STRING_END,
+ NUMBER_END,
+ SL_COMMENT_END,
+ ML_COMMENT_END,
+ ESC_CHAR_END,
+ DIRECTIVE_END,
+ SYMBOL_END,
+ KEYWORD_END,
+ IDENTIFIER_BEGIN,
+ IDENTIFIER_END,
+ EMBEDDED_CODE_BEGIN,
+ EMBEDDED_CODE_END,
+ EMBEDDED_PERL_HACK,
+
+ _UNKNOWN=100,
+ _EOL,
+ _EOF,
+ _WS
+ } ;
+
+ /** Parser return values*/
+ enum ParseError
+ {
+ PARSE_OK,
+ BAD_INPUT=1,
+ BAD_OUTPUT=2,
+ BAD_STYLE=4,
+ BAD_BINARY=8
+ };
+
+ /** line wrapping modes*/
+ enum WrapMode
+ {
+ WRAP_DISABLED,
+ WRAP_SIMPLE,
+ WRAP_DEFAULT
+ };
+
+ /** language definition loading results*/
+ enum LoadResult
+ {
+ LOAD_FAILED,
+ LOAD_FAILED_REGEX,
+ LOAD_NEW,
+ LOAD_NONE
+ };
+
+ /** output formats */
+ enum OutputType
+ {
+ HTML,
+ XHTML,
+ TEX,
+ LATEX,
+ RTF,
+ XML,
+ ANSI,
+ XTERM256,
+ HTML32,
+ SVG,
+ BBCODE
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/htmlgenerator.cpp b/support/highlight/src/core/htmlgenerator.cpp
new file mode 100644
index 0000000000..b21421c51c
--- /dev/null
+++ b/support/highlight/src/core/htmlgenerator.cpp
@@ -0,0 +1,477 @@
+/***************************************************************************
+ htmlgenerator.cpp - description
+ -------------------
+ begin : Wed Nov 28 2001
+ copyright : (C) 2001-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+#include "htmlgenerator.h"
+#include "version.h"
+
+using namespace std;
+
+namespace highlight
+{
+
+ HtmlGenerator::HtmlGenerator () :
+ CodeGenerator ( HTML ),
+ brTag ( "<br>" ),
+ hrTag ( "<hr>" ),
+ idAttr ( "name" ),
+ fileSuffix ( ".html" ),
+ cssClassName ( "hl" ),
+ orderedList ( false ),
+ useInlineCSS ( false ),
+ enclosePreTag ( false ),
+ attachAnchors ( false ),
+ anchorPrefix ( "l" )
+ {
+ spacer = " ";
+ styleCommentOpen="/*";
+ styleCommentClose="*/";
+ }
+
+ string HtmlGenerator::getHeader()
+ {
+ ostringstream os;
+ os << getHeaderStart ( docTitle );
+ if ( !useInlineCSS )
+ {
+ if ( includeStyleDef )
+ {
+ os << "<style type=\"text/css\">\n<!--\n";
+ os << getStyleDefinition();
+ os << CodeGenerator::readUserStyleDef();
+ os << "//-->\n</style>\n";
+ }
+ else
+ {
+ os << "<link rel=\"stylesheet\" type=\"text/css\" href=\""
+ << getStyleOutputPath()
+ << "\">\n";
+ }
+ os << "</head>\n<body class=\"" << cssClassName
+ << "\">\n";
+ }
+ else
+ {
+ os << "</head>\n<body style=\""
+ << "background-color:#"
+ << ( docStyle.getBgColour().getRed ( HTML ) )
+ << ( docStyle.getBgColour().getGreen ( HTML ) )
+ << ( docStyle.getBgColour().getBlue ( HTML ) )
+ << "\">\n";
+ }
+
+ return os.str();
+ }
+
+ string HtmlGenerator::getFooter()
+ {
+ return getGeneratorComment();
+ }
+
+ void HtmlGenerator::printBody()
+ {
+ if ( !fragmentOutput || enclosePreTag )
+ {
+ if ( !useInlineCSS )
+ {
+ *out << "<pre class=\"" << cssClassName
+ << "\">";
+ }
+ else
+ {
+ *out << "<pre style=\""
+ << "color:#"
+ << ( docStyle.getDefaultStyle().getColour().getRed ( HTML ) )
+ << ( docStyle.getDefaultStyle().getColour().getGreen ( HTML ) )
+ << ( docStyle.getDefaultStyle().getColour().getBlue ( HTML ) )
+ << "; background-color:#"
+ << ( docStyle.getBgColour().getRed ( HTML ) )
+ << ( docStyle.getBgColour().getGreen ( HTML ) )
+ << ( docStyle.getBgColour().getBlue ( HTML ) )
+ << "; font-size:" << this->getBaseFontSize()
+ << "pt; font-family:'" << this->getBaseFont() <<"';\">";
+ }
+ }
+ if ( showLineNumbers && orderedList ) *out << "<ol>";
+
+ processRootState();
+
+ if ( showLineNumbers && orderedList ) *out << "\n</ol>";
+
+ if ( !fragmentOutput || enclosePreTag ) *out << "</pre>";
+ }
+
+
+ void HtmlGenerator::initOutputTags ()
+ {
+ openTags.push_back ( "" );
+ if ( useInlineCSS )
+ {
+ //embedBlockOpen = "<div style=\"background-color:#efefef;\">";
+ openTags.push_back ( getOpenTag ( docStyle.getStringStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getNumberStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getSingleLineCommentStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getCommentStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getEscapeCharStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getDirectiveStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getDirectiveStringStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getLineStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getSymbolStyle() ) );
+ }
+ else
+ {
+ //embedBlockOpen = "<div style=\"background-color:#efefef;\">";
+ openTags.push_back ( getOpenTag ( STY_NAME_STR ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_NUM ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_SLC ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_COM ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_ESC ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_DIR ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_DST ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_LIN ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_SYM ) );
+ }
+
+ closeTags.push_back ( "" );
+ for ( int i=1;i<NUMBER_BUILTIN_STATES; i++ )
+ {
+ closeTags.push_back ( "</span>" );
+ }
+ //embedBlockClose = "</div>";
+ }
+
+ string HtmlGenerator::getAttributes ( const string & elemName, const ElementStyle & elem )
+ {
+ ostringstream s;
+ if ( !elemName.empty() )
+ {
+ s << "."<<cssClassName<<"."<<elemName<<" { ";
+ }
+ s << "color:#"
+ << ( elem.getColour().getRed ( HTML ) )
+ << ( elem.getColour().getGreen ( HTML ) )
+ << ( elem.getColour().getBlue ( HTML ) )
+ << ( elem.isBold() ? "; font-weight:bold" :"" )
+ << ( elem.isItalic() ? "; font-style:italic" :"" )
+ << ( elem.isUnderline() ? "; text-decoration:underline" :"" );
+ if ( !elemName.empty() )
+ {
+ s << "; }\n" ;
+ }
+ return s.str();
+ }
+
+ string HtmlGenerator::getOpenTag ( const string& styleName )
+ {
+ return "<span class=\""+cssClassName+ " " + styleName + "\">";
+ }
+
+ string HtmlGenerator::getOpenTag ( const ElementStyle & elem )
+ {
+ return "<span style=\""+getAttributes ( "",elem ) + "\">";
+ }
+
+ string HtmlGenerator::getGeneratorComment()
+ {
+ ostringstream s;
+ s <<"\n</body>\n</html>\n<!--HTML generated by highlight "
+ << HIGHLIGHT_VERSION << ", " << HIGHLIGHT_URL <<"-->\n";
+
+ return s.str();
+ }
+
+ string HtmlGenerator::getStyleDefinition()
+ {
+ if ( styleDefinitionCache.empty() )
+ {
+ ostringstream os;
+ os << "body."<<cssClassName<<"\t{ background-color:#"
+ << ( docStyle.getBgColour().getRed ( HTML ) )
+ << ( docStyle.getBgColour().getGreen ( HTML ) )
+ << ( docStyle.getBgColour().getBlue ( HTML ) )
+ << "; }\n";
+ os << "pre."<<cssClassName<<"\t{ color:#"
+ << ( docStyle.getDefaultStyle().getColour().getRed ( HTML ) )
+ << ( docStyle.getDefaultStyle().getColour().getGreen ( HTML ) )
+ << ( docStyle.getDefaultStyle().getColour().getBlue ( HTML ) )
+ << "; background-color:#"
+ << ( docStyle.getBgColour().getRed ( HTML ) )
+ << ( docStyle.getBgColour().getGreen ( HTML ) )
+ << ( docStyle.getBgColour().getBlue ( HTML ) )
+ << "; font-size:" << this->getBaseFontSize();
+
+ os << "pt; font-family:'" << this->getBaseFont() << "';}\n";
+
+ if ( orderedList )
+ {
+ os << "li."<<cssClassName<<"\t{ margin-bottom:-"<<this->getBaseFontSize() <<"pt; }\n";
+ }
+
+ os << getAttributes ( STY_NAME_NUM, docStyle.getNumberStyle() )
+ << getAttributes ( STY_NAME_ESC, docStyle.getEscapeCharStyle() )
+ << getAttributes ( STY_NAME_STR, docStyle.getStringStyle() )
+ << getAttributes ( STY_NAME_DST, docStyle.getDirectiveStringStyle() )
+ << getAttributes ( STY_NAME_SLC, docStyle.getSingleLineCommentStyle() )
+ << getAttributes ( STY_NAME_COM, docStyle.getCommentStyle() )
+ << getAttributes ( STY_NAME_DIR, docStyle.getDirectiveStyle() )
+ << getAttributes ( STY_NAME_SYM, docStyle.getSymbolStyle() )
+ << getAttributes ( STY_NAME_LIN, docStyle.getLineStyle() );
+
+ os << "."<<cssClassName<<".mark\t{ background-color:#"
+ << ( docStyle.getMarkLineColour().getRed ( HTML ) )
+ << ( docStyle.getMarkLineColour().getGreen ( HTML ) )
+ << ( docStyle.getMarkLineColour().getBlue ( HTML ) )
+ << ";}\n";
+
+ KeywordStyles styles = docStyle.getKeywordStyles();
+ for ( KSIterator it=styles.begin(); it!=styles.end(); it++ )
+ {
+ os << getAttributes ( it->first, it->second );
+ }
+ styleDefinitionCache=os.str();
+ }
+ return styleDefinitionCache;
+ }
+
+ string HtmlGenerator::maskCharacter ( unsigned char c )
+ {
+ switch ( c )
+ {
+ case '<' :
+ return "&lt;";
+ break;
+ case '>' :
+ return "&gt;";
+ break;
+ case '&' :
+ return "&amp;";
+ break;
+ case '\"' :
+ return "&quot;";
+ break;
+
+ case '@' :
+ return "&#64;";
+ break;
+
+ default :
+ return string ( 1, c );
+ }
+ }
+
+ string HtmlGenerator::getNewLine()
+ {
+
+ string nlStr;
+
+ if ( markLines.count ( lineNumber-1 ) ) nlStr +="</span>";
+
+ if ( showLineNumbers && orderedList ) nlStr +="</li>";
+ /// set wrapping arrow if previous line was wrapped
+ //else if (preFormatter.isWrappedLine(lineNumber-1)) nlStr += "&crarr;";
+
+ if (printNewLines) nlStr+="\n";
+
+ return nlStr;
+ }
+
+ void HtmlGenerator::insertLineNumber ( bool insertNewLine )
+ {
+ if ( insertNewLine )
+ {
+ wsBuffer += getNewLine();
+ }
+ if ( showLineNumbers )
+ {
+ ostringstream numberPrefix;
+ int lineNo = lineNumber+lineNumberOffset;
+ if ( orderedList )
+ {
+ if ( useInlineCSS )
+ {
+ numberPrefix<<"<li style=\""<<getAttributes ( "", docStyle.getLineStyle() ) <<"\">";
+ }
+ else
+ {
+ numberPrefix<<"<li class=\""<<cssClassName<<"\">";
+ }
+ // Opera 8 ignores empty list items -> add &nbsp;
+ if ( line.empty() ) numberPrefix<<"&nbsp;";
+ }
+ if ( attachAnchors )
+ numberPrefix << "<a "
+ << idAttr
+ << "=\""
+ << anchorPrefix
+ << "_"
+ << lineNo
+ << "\"></a>";
+
+ if ( !orderedList )
+ {
+ ostringstream os;
+ if ( lineNumberFillZeroes ) os.fill ( '0' );
+ os <<setw ( getLineNumberWidth() ) <<right<< lineNo;
+ numberPrefix << openTags[LINENUMBER]
+ << os.str()
+ << spacer
+ << closeTags[LINENUMBER];
+ }
+ wsBuffer += numberPrefix.str();
+ }
+
+ if ( markLines.count ( lineNumber ) )
+ {
+ if ( useInlineCSS )
+ {
+ ostringstream markingFmt;
+ markingFmt <<"<span style=\""
+ <<"background-color:#"
+ << ( docStyle.getMarkLineColour().getRed ( HTML ) )
+ << ( docStyle.getMarkLineColour().getGreen ( HTML ) )
+ << ( docStyle.getMarkLineColour().getBlue ( HTML ) )
+ << ";\"";
+ wsBuffer+=markingFmt.str();
+ }
+ else
+ {
+ wsBuffer +="<span class=\""+cssClassName+" mark\"";
+ }
+ if ( !markLines[lineNumber].empty() )
+ wsBuffer +=" title=\""+markLines[lineNumber]+"\"";
+ wsBuffer +=">";
+ }
+
+ }
+
+ string HtmlGenerator::getHeaderStart ( const string &title )
+ {
+ ostringstream header;
+ header<< "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">"
+ << "\n<html>\n<head>\n";
+ if ( encodingDefined() )
+ {
+ header << "<meta http-equiv=\"content-type\" content=\"text/html; charset="
+ << encoding
+ << "\">\n";
+ }
+ header << "<title>"
+ << title
+ << "</title>\n";
+ return header.str();
+ }
+
+ bool HtmlGenerator::printIndexFile ( const vector<string> &fileList,
+ const string &outPath )
+ {
+ string suffix = fileSuffix;
+ string outFilePath = outPath + "index" + suffix;
+ ofstream indexfile ( outFilePath.c_str() );
+
+ if ( !indexfile.fail() )
+ {
+ string inFileName;
+ string inFilePath, newInFilePath;
+ indexfile << getHeaderStart ( "Source Index" );
+ indexfile << "</head>\n<body>\n<h1> Source Index</h1>\n"
+ << hrTag
+ << "\n<ul>\n";
+ string::size_type pos;
+ for ( unsigned int i=0; i < fileList.size(); i++ )
+ {
+ pos= ( fileList[i] ).find_last_of ( Platform::pathSeparator );
+ if ( pos!=string::npos )
+ {
+ newInFilePath = ( fileList[i] ).substr ( 0, pos+1 );
+ }
+ else
+ {
+ newInFilePath=Platform::pathSeparator;
+ }
+ if ( newInFilePath!=inFilePath )
+ {
+ indexfile << "</ul>\n<h2>";
+ indexfile << newInFilePath;
+ indexfile << "</h2>\n<ul>\n";
+ inFilePath=newInFilePath;
+ }
+ inFileName = ( fileList[i] ).substr ( pos+1 );
+ indexfile << "<li><a href=\"" << inFileName << suffix << "\">";
+ indexfile << inFileName << suffix <<"</a></li>\n";
+ }
+
+ indexfile << "</ul>\n"
+ << hrTag << brTag
+ << "<small>Generated by highlight "
+ << HIGHLIGHT_VERSION
+ << ", <a href=\"" << HIGHLIGHT_URL << "\" target=\"new\">"
+ << HIGHLIGHT_URL << "</a></small>";
+ indexfile << getGeneratorComment();
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+
+ string HtmlGenerator::getKeywordOpenTag ( unsigned int styleID )
+ {
+ if ( useInlineCSS )
+ {
+ return getOpenTag ( docStyle.getKeywordStyle ( langInfo.getKeywordClasses() [styleID] ) );
+ }
+ return getOpenTag ( langInfo.getKeywordClasses() [styleID] );
+ }
+
+ string HtmlGenerator::getKeywordCloseTag ( unsigned int styleID )
+ {
+ return "</span>";
+ }
+
+ string HtmlGenerator::getMetaInfoOpenTag ( const TagInfo& info )
+ {
+ ostringstream tagStream;
+ tagStream<<"<span title=\""<<info.getKind() <<" | ";
+ if ( !info.name_space.empty() )
+ {
+ maskString ( tagStream, info.name_space );
+ tagStream<<" | ";
+ }
+ maskString ( tagStream, info.file ) ;
+ tagStream<<"\">";
+ return tagStream.str();
+ }
+ string HtmlGenerator::getMetaInfoCloseTag()
+ {
+ return "</span>";
+ }
+
+}
diff --git a/support/highlight/src/core/htmlgenerator.h b/support/highlight/src/core/htmlgenerator.h
new file mode 100644
index 0000000000..29e650839f
--- /dev/null
+++ b/support/highlight/src/core/htmlgenerator.h
@@ -0,0 +1,195 @@
+/***************************************************************************
+ htmlgenerator.h - description
+ -------------------
+ begin : Wed Nov 28 2001
+ copyright : (C) 2001-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+
+#ifndef HTMLGENERATOR_H
+#define HTMLGENERATOR_H
+
+#include <string>
+
+#include "codegenerator.h"
+
+#include "stylecolour.h"
+#include "elementstyle.h"
+
+namespace highlight
+{
+
+ /**
+ \brief This class generates HTML.
+
+ It contains information about the resulting document structure (document
+ header and footer), the colour system, white space handling and text
+ formatting attributes.
+
+ * @author Andre Simon
+ */
+
+ class HtmlGenerator : public highlight::CodeGenerator
+ {
+ public:
+
+ HtmlGenerator();
+
+ /** Destructor, virtual as it is base for xhtmlgenerator*/
+ virtual ~HtmlGenerator() {};
+
+ /** Print style definitions to external file
+ \param outFile Path of external style definition
+ */
+ bool printExternalStyle ( const string &outFile );
+
+ /** Print index file with all input file names
+ \param fileList List of output file names
+ \param outPath Output path
+ */
+ bool printIndexFile ( const vector<string> & fileList, const string &outPath );
+
+ /**
+ \param b set true if anchors should be attached to line numbers
+ */
+ void setHTMLAttachAnchors ( bool b ) { attachAnchors = b; }
+
+ /**
+ \param prefix anchor prefix
+ */
+ void setHTMLAnchorPrefix ( const string & prefix ) { anchorPrefix = prefix; }
+
+ /**
+ \param b if true line numbers should be replaced by list items
+ */
+ void setHTMLOrderedList ( bool b ) { orderedList = b; }
+
+ /**
+ \param b if true CSS formatting will be inserted into each tag
+ */
+ void setHTMLInlineCSS ( bool b ) { useInlineCSS = b; }
+
+ /**
+ \param b if truefragmented output will be enclosed in pre tag
+ */
+ void setHTMLEnclosePreTag ( bool b ) { enclosePreTag = b; }
+
+ /**
+ \param name CSS Class name
+ */
+ void setHTMLClassName ( const string& name )
+ {
+ cssClassName = name;
+ }
+
+ protected:
+
+ string brTag, ///< break tag
+ hrTag, ///< horizontal ruler tag
+ idAttr, ///< ID tag
+ fileSuffix, ///< filename extension
+ cssClassName; ///< css class name prefix
+
+ /** caches style definition */
+ string styleDefinitionCache;
+
+ /** line count should be replaced by ordered list*/
+ bool orderedList;
+
+ /** CSS definition should be outputted inline */
+ bool useInlineCSS;
+
+ /** pre tag should be outputted in fragment mode*/
+ bool enclosePreTag;
+
+ /** \return CSS definition */
+ string getStyleDefinition();
+
+ /** \return Content of user defined style file */
+ string readUserStyleDef();
+
+ /** \param title Dociment title
+ \return Start of file header */
+ virtual string getHeaderStart ( const string &title );
+
+ /** \return Comment with program information */
+ string getGeneratorComment();
+
+ private:
+
+ /** insert line number in the beginning of the new line
+ */
+ virtual void insertLineNumber ( bool insertNewLine=true );
+
+ /** Print document header
+ */
+ string getHeader();
+
+ /** Print document body*/
+ void printBody();
+
+ /** Print document footer*/
+ string getFooter();
+
+ /** initialize tags in specific format according to colouring information provided in DucumentStyle */
+ void initOutputTags();
+
+ /** \param styleName Style name
+ \return Opening tag of the given style
+ */
+ string getOpenTag ( const string& styleName );
+
+ string getOpenTag ( const ElementStyle & elem );
+
+ /** \return escaped character*/
+ virtual string maskCharacter ( unsigned char );
+
+ /** test if anchors should be appied to line numbers*/
+ bool attachAnchors;
+
+ /**Optional anchor prefix */
+ string anchorPrefix;
+
+ /**\return text formatting attributes in HTML format */
+ string getAttributes ( const string & elemName, const ElementStyle & elem );
+
+ /** \param styleID Style ID
+ \return Opening tag of the given style
+ */
+ string getKeywordOpenTag ( unsigned int styleID );
+
+ /** \param styleID Style ID
+ \return Closing tag of the given style
+ */
+ string getKeywordCloseTag ( unsigned int styleID );
+
+ /** @return Newline string */
+ string getNewLine();
+
+ string getMetaInfoOpenTag ( const TagInfo& info );
+ string getMetaInfoCloseTag();
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/languagedefinition.cpp b/support/highlight/src/core/languagedefinition.cpp
new file mode 100644
index 0000000000..e52688c910
--- /dev/null
+++ b/support/highlight/src/core/languagedefinition.cpp
@@ -0,0 +1,396 @@
+/***************************************************************************
+ languagedefinition.cpp - description
+ -------------------
+ begin : Wed Nov 28 2001
+ copyright : (C) 2001-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <memory>
+
+#include "languagedefinition.h"
+#include "stringtools.h"
+
+
+using namespace std;
+
+namespace highlight
+{
+
+ const string LanguageDefinition::REGEX_IDENTIFIER =
+ "[a-zA-Z_]\\w*";
+
+ const string LanguageDefinition::REGEX_NUMBER =
+ "(?:0x|0X)[0-9a-fA-F]+|\\d*[\\.]?\\d+(?:[eE][\\-\\+]\\d+)?[lLuU]*";
+
+ LanguageDefinition::LanguageDefinition() :
+ ignoreCase ( false ),
+ disableHighlighting ( false ),
+ allowExtEscape ( false ),
+ allowNestedComments ( true ),
+ reformatCode ( false )
+ {
+ reDefPattern=Pattern::compile ( "^regex\\((.+?)(,\\s*(\\d+))?\\)$" );
+ }
+
+ LanguageDefinition::~LanguageDefinition()
+ {
+ for ( vector<RegexElement*>::iterator it=regex.begin(); it!=regex.end();it++ )
+ {
+ delete *it;
+ }
+ delete reDefPattern;
+ }
+
+ int LanguageDefinition::isKeyword ( const string &s )
+ {
+ return ( s.length() && keywords.count ( s ) ) ? keywords[s] : 0;
+ }
+
+ void LanguageDefinition::addSymbol ( stringstream& symbolStream,
+ State stateBegin,
+ State stateEnd,
+ bool isDelimiter,
+ const string& paramValue,
+ unsigned int classID )
+ {
+ RegexDef re = extractRegex ( paramValue );
+ if ( !re.reString.empty() )
+ {
+ Pattern* p = Pattern::compile ( re.reString );
+ if ( p!=NULL ) {
+ regex.push_back ( new RegexElement ( stateBegin,stateEnd, p, re.capturingGroup ) );
+ } else {
+ failedRegex = re.reString;
+ }
+ return;
+ }
+ if ( isDelimiter )
+ {
+ addDelimiterSymbol ( symbolStream, stateBegin, stateEnd, paramValue, classID );
+ }
+ else
+ {
+ addSimpleSymbol ( symbolStream, stateBegin,paramValue );
+ }
+ }
+
+ RegexDef LanguageDefinition::extractRegex ( const string &paramValue )
+ {
+ RegexDef re_def;
+ auto_ptr<Matcher> m ( reDefPattern->createMatcher ( paramValue ) );
+ if ( m.get() && m->matches() )
+ {
+ re_def.reString = m->getGroup ( 1 );
+ if ( m->getStartingIndex ( 3 ) !=-1 )
+ {
+ StringTools::str2num<int> ( re_def.capturingGroup, m->getGroup ( 3 ), std::dec );
+ //std::cerr << "capturingGroup "<<re_def.capturingGroup<<"\n";
+ }
+ }
+ return re_def;
+ }
+
+ void LanguageDefinition::addSimpleSymbol ( stringstream& symbolStream,
+ State state,
+ const string& paramValue )
+ {
+ istringstream valueStream ( paramValue );
+ bool valExists=false;
+ string value;
+ int pairCount =0;
+ while ( valueStream >> value )
+ {
+ symbolStream << " " << value;
+ valExists = true;
+ delimiterPair[value] = ++pairCount;
+ }
+ if ( valExists )
+ {
+ symbolStream << " " << state;
+ }
+ }
+
+ void LanguageDefinition::addDelimiterSymbol ( stringstream& symbolStream,
+ State stateBegin, State stateEnd,
+ const string& paramValue,
+ unsigned int classID )
+ {
+ istringstream valueStream ( paramValue );
+ string delimPrefix, delimSuffix;
+ int pairCount =0;
+ while ( valueStream>>delimPrefix )
+ {
+ valueStream >> delimSuffix;
+ symbolStream << " "<<delimPrefix <<" " << stateBegin;
+ symbolStream <<" "<< delimSuffix<<" "<< stateEnd;
+ delimiterPrefixes.insert ( make_pair ( delimPrefix, classID ) );
+ // if no closing delimiter exists, open and close delims are equal:
+ delimiterDistinct[stateBegin] = !delimSuffix.empty();
+ ++pairCount;
+ delimiterPair[delimPrefix] = delimiterPair[delimSuffix] = pairCount;
+ //std::cout << "pair: "<< delimPrefix<<"->"<<delimiterPair[delimPrefix]
+ // <<", "<<delimSuffix<<"->"<<delimiterPair[delimSuffix]<<"\n";
+ }
+ }
+
+ void LanguageDefinition::addDelimiterRegex ( stringstream& symbolStream,
+ State stateBegin, State stateEnd,
+ const string& paramValue, const string& langName )
+ {
+ istringstream valueStream ( paramValue );
+ string delimStart, delimEnd;
+ valueStream>>delimStart;
+ valueStream>>delimEnd;
+
+ RegexDef reStart = extractRegex ( delimStart );
+ if ( !reStart.reString.empty() )
+ {
+ Pattern* p = Pattern::compile ( reStart.reString );
+ if ( p!=NULL ) {
+ regex.insert (regex.begin(),1, new RegexElement ( stateBegin,stateBegin, p, reStart.capturingGroup, -1, langName ) );
+ }
+ }
+ // end regex string needs to be saved to pass it back to host language when embedded section is over
+ //host language definiton needs to know end delimiter to recognize single line embedded sections
+ RegexDef reEnd = extractRegex ( delimEnd );
+ if ( !reEnd.reString.empty() )
+ {
+ exitDelimiters[getNewPath(langName)]=reEnd.reString;
+ }
+ }
+
+ void LanguageDefinition::restoreLangEndDelim(const string& langPath){
+ if ( !langPath.empty()&& exitDelimiters.count(langPath) )
+ {
+ Pattern* p = Pattern::compile ( exitDelimiters[langPath]);
+ if ( p!=NULL ) {
+ regex.insert (regex.begin(),1, new RegexElement ( EMBEDDED_CODE_END,EMBEDDED_CODE_END, p ) );
+ }
+ //else
+ // cerr<<"Pattern::compile fehler\n";
+ }
+ }
+
+
+ void LanguageDefinition::getFlag ( string& paramValue, bool &flag)
+ {
+ if (paramValue.size()) flag= StringTools::change_case ( paramValue ) =="true";
+ }
+
+ void LanguageDefinition::getSymbol ( const string& paramValue, unsigned char &symbol )
+ {
+ if (paramValue.empty()) return;
+ symbol=paramValue[0];
+
+/*
+ istringstream valueStream ( paramValue );
+ unsigned char symbol;
+ valueStream >> symbol;
+ return symbol;
+*/
+ }
+
+ void LanguageDefinition::addKeywords ( const string &kwList,
+ State stateBegin, State stateEnd,
+ int classID )
+ {
+ RegexDef re = extractRegex ( kwList );
+ if ( !re.reString.empty() )
+ {
+ Pattern* p = Pattern::compile ( re.reString );
+ if ( p!=NULL )
+ regex.push_back ( new RegexElement ( stateBegin,stateEnd, p, classID, re.capturingGroup ) );
+ else
+ failedRegex = re.reString;
+ return;
+ }
+ istringstream valueStream ( kwList );
+ string keyword;
+ while ( valueStream >> keyword )
+ {
+ keywords.insert ( make_pair ( keyword, classID ) );
+ }
+ }
+
+ unsigned int LanguageDefinition::generateNewKWClass ( const string& newClassName )
+ {
+ unsigned int newClassID=0;
+ bool found=false;
+ while ( newClassID<keywordClasses.size() && !found )
+ {
+ found = ( newClassName==keywordClasses[newClassID++] );
+ }
+ if ( !found )
+ {
+ newClassID++;
+ keywordClasses.push_back ( newClassName );
+ }
+ return newClassID;
+ }
+
+ bool LanguageDefinition::load ( const string& langDefPath, bool clear )
+ {
+ if ( clear ) reset();
+
+ ConfigurationReader langDef ( langDefPath );
+ if ( !langDef.found() )
+ {
+ currentPath.clear();
+ return false;
+ }
+ currentPath=langDefPath;
+ disableHighlighting=false;
+ string token;
+ stringstream symbolStrStream;
+
+ addSymbol ( symbolStrStream,
+ STRING,
+ STRING_END,
+ false,
+ langDef.getParameter ( "stringdelimiters" ) );
+
+ addSymbol ( symbolStrStream,
+ STRING,
+ STRING_END,
+ true,
+ langDef.getParameter ( "string_unequal" ) );
+
+ addSymbol ( symbolStrStream,
+ DIRECTIVE,
+ DIRECTIVE_END,
+ false,
+ langDef.getParameter ( "directive" ) );
+
+ addSymbol ( symbolStrStream,
+ ESC_CHAR,
+ ESC_CHAR_END,
+ false,
+ langDef.getParameter ( "escchar" ) );
+
+ addSymbol ( symbolStrStream,
+ SL_COMMENT,
+ SL_COMMENT_END,
+ false,
+ langDef.getParameter ( "sl_comment" ) );
+
+ addSymbol ( symbolStrStream,
+ ML_COMMENT,
+ ML_COMMENT_END,
+ true,
+ langDef.getParameter ( "ml_comment" ) );
+
+ addSymbol ( symbolStrStream,
+ ML_COMMENT,
+ ML_COMMENT_END,
+ false,
+ langDef.getParameter ( "ml_comment_equal" ) );
+
+ addSymbol ( symbolStrStream,
+ SYMBOL,
+ SYMBOL_END,
+ false,
+ langDef.getParameter ( "symbols" ) );
+
+ string paramName, className, classValue;
+ vector<string> paramNames=langDef.getParameterNames();
+ for ( unsigned int i=0;i<paramNames.size();i++ )
+ {
+ paramName=paramNames[i];
+ className=StringTools::getParantheseVal ( paramName );
+ classValue=langDef.getParameter ( paramName );
+ if ( paramName.find ( "keywords" ) != string::npos )
+ {
+ addKeywords ( classValue, KEYWORD, KEYWORD_END, generateNewKWClass ( className ) );
+ } else if (paramName.find ( "nested" ) != string::npos) {
+ addDelimiterRegex( symbolStrStream, EMBEDDED_CODE_BEGIN, EMBEDDED_CODE_END,
+ classValue, className );
+ }
+ }
+
+ // use hardcoded regex if not defined in language definition
+ // TODO save as members to alloe redefinition in langdefs with include stmt
+ string user_def_re = extractRegex ( langDef.getParameter ( "digit" ) ).reString;
+ string re_digit = ( user_def_re.empty() ) ? REGEX_NUMBER : user_def_re;
+
+ user_def_re = extractRegex ( langDef.getParameter ( "identifier" ) ).reString;
+ string re_identifier= ( user_def_re.empty() ) ? REGEX_IDENTIFIER: user_def_re;
+
+ // insert identifier and number regex after keyword regexes
+ regex.push_back ( new RegexElement ( IDENTIFIER_BEGIN, IDENTIFIER_END,
+ Pattern::compile ( re_identifier ) ) );
+ regex.push_back ( new RegexElement ( NUMBER, NUMBER_END,
+ Pattern::compile ( re_digit ) ) );
+
+ symbolString = symbolStrStream.str();
+
+ getFlag ( langDef.getParameter ( "ignorecase" ), ignoreCase);
+ getFlag ( langDef.getParameter ( "allownestedcomments" ), allowNestedComments );
+ getFlag ( langDef.getParameter ( "disablehighlighting" ), disableHighlighting );
+ getFlag ( langDef.getParameter ( "reformatting" ), reformatCode );
+ getSymbol ( langDef.getParameter ( "rawstringprefix" ), rawStringPrefix );
+ getSymbol ( langDef.getParameter ( "continuationsymbol" ), continuationChar );
+ getFlag ( langDef.getParameter ( "allowextescape" ), allowExtEscape);
+
+ langDesc = langDef.getParameter ( "description" );
+
+ //load syntax before it is overridden by calling language definition
+ string fileToInclude=langDef.getParameter ( "include" );
+ if ( !fileToInclude.empty() )
+ {
+ //string::size_type Pos = langDefPath.find_last_of ( Platform::pathSeparator );
+ //string includeLangDefPath = langDefPath.substr ( 0, Pos+1 ) + fileToInclude;
+ //load ( includeLangDefPath, false );
+ load(getNewPath(fileToInclude), false);
+ }
+
+ return failedRegex.empty();
+ }
+
+ void LanguageDefinition::reset()
+ {
+ keywords.clear();
+ keywordClasses.clear();
+ delimiterPrefixes.clear();
+ delimiterDistinct.clear();
+ delimiterPair.clear();
+ langDesc.clear();
+ ignoreCase= false;
+ allowNestedComments= reformatCode = false;
+ rawStringPrefix = continuationChar = '\0';
+ disableHighlighting=allowExtEscape=false;
+
+ // TODO eigene methode
+ for ( vector<RegexElement*>::iterator it=regex.begin(); it!=regex.end();it++ )
+ {
+ delete *it;
+ }
+ regex.clear();
+ failedRegex.clear();
+ }
+
+ string LanguageDefinition::getNewPath(const string& lang){
+ string::size_type Pos = currentPath.find_last_of ( Platform::pathSeparator );
+ return currentPath.substr ( 0, Pos+1 ) + lang + ".lang";
+ }
+
+}
diff --git a/support/highlight/src/core/languagedefinition.h b/support/highlight/src/core/languagedefinition.h
new file mode 100644
index 0000000000..08caee3fc3
--- /dev/null
+++ b/support/highlight/src/core/languagedefinition.h
@@ -0,0 +1,325 @@
+/***************************************************************************
+ languagedefinition.h - description
+ -------------------
+ begin : Wed Nov 28 2001
+ copyright : (C) 2001-2008 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef LANGUAGEDEFINITION_H
+#define LANGUAGEDEFINITION_H
+
+#include <string>
+#include <map>
+#include <iostream>
+#include <fstream>
+#include <iterator>
+#include <sstream>
+
+#include "configurationreader.h"
+#include "platform_fs.h"
+#include "enums.h"
+#include "re/Pattern.h"
+#include "re/Matcher.h"
+
+namespace highlight
+{
+
+ class RegexElement;
+
+ /** maps keywords and the corresponding class IDs*/
+ typedef map <string, int> KeywordMap;
+
+ /** maps embedded langiage names to exit delimiter regexes*/
+ typedef map <string, string> EmbedLangDelimMap;
+
+ /**\brief Contains specific data of the programming language being processed.
+
+ The load() method will only read a new language definition if the given
+ file path is not equal to the path of the current language definition.
+
+ * @author Andre Simon
+ */
+
+ class LanguageDefinition
+ {
+
+ public:
+
+ LanguageDefinition();
+
+ ~LanguageDefinition();
+
+ /** \return Symbol string, containg all known symbols with the referencing state ids*/
+ const string &getSymbolString() const { return symbolString; }
+
+ /** \return Failed regilar expression */
+ const string &getFailedRegex() const { return failedRegex; }
+
+ /** \return Prefix of raw strings */
+ unsigned char getRawStringPrefix() const { return rawStringPrefix; }
+
+ /** \return Continuation Character */
+ unsigned char getContinuationChar() const { return continuationChar; }
+
+ /** \return true if syntax highlighting is enabled*/
+ bool highlightingEnabled() const { return !disableHighlighting;}
+
+ /** \return True if language is case sensitive */
+ bool isIgnoreCase() const { return ignoreCase;}
+
+ /** \param s String
+ \return class id of keyword, 0 if s is not a keyword */
+ int isKeyword ( const string &s ) ;
+
+ /** Load new language definition
+ \param langDefPath Path of language definition
+ \param clear Test if former data should be deleted
+ \return True if successfull */
+ bool load ( const string& langDefPath, bool clear=true );
+
+ /** \return True if multi line comments may be nested */
+ bool allowNestedMLComments() const { return allowNestedComments; }
+
+ /** \return True if highlighting is disabled
+ TODO remove method */
+ bool highlightingDisabled() const { return disableHighlighting; }
+
+ /** \return True if the next load() call would load a new language definition
+ \param langDefPath Path to language definition */
+ bool needsReload ( const string &langDefPath ) const { return currentPath!=langDefPath; }
+
+ /** \return True if current language may be reformatted (c, c++, c#, java) */
+ bool enableReformatting() const { return reformatCode;}
+
+ /** \return True if escape sequences are allowed outsde of strings */
+ bool allowExtEscSeq() const { return allowExtEscape; }
+
+ /** \return keywords*/
+ const KeywordMap& getKeywords() const { return keywords; }
+
+ /** \return keyword classes*/
+ const vector<string>& getKeywordClasses() const { return keywordClasses;}
+
+ /** \return regular expressions */
+ const vector<RegexElement*>& getRegexElements() const {return regex;};
+
+ /** \return description of the programming language */
+ const string & getDescription () const {return langDesc;}
+
+ /** \param stateID state id
+ \return true, if no closing delimiter exists (open and close delimiters are equal)
+ */
+ bool delimiterIsDistinct ( int stateID )
+ {
+ return delimiterDistinct[stateID];
+ }
+
+ /** Pairs of open/close tokens have a unique ID to test if two tokens act as delimiters
+ \param token delimiter token
+ \return token ID
+ */
+ int getDelimiterPairID ( const string& token )
+ {
+ return delimiterPair[token];
+ }
+
+ string getDelimRegex(const string & lang){
+ return exitDelimiters[lang];
+ }
+
+ /** initializes end delimiter regex to switch back to host language
+ \param langPath path of embedded language definition
+ */
+ void restoreLangEndDelim(const string&langPath);
+
+ /**
+ \param lang language definition name (no path, no ".lang" extension)
+ \return absolute path based on the previously loaded definition
+ */
+ string getNewPath(const string& lang);
+
+ string getCurrentPath() { return currentPath;}
+
+ private:
+
+ static const string REGEX_IDENTIFIER;
+ static const string REGEX_NUMBER;
+
+ // string containing symbols and their IDs of the programming language
+ string symbolString;
+
+ // path to laoded language definition
+ string currentPath;
+
+ // Language description
+ string langDesc;
+
+ string failedRegex;
+
+ KeywordMap keywords;
+
+ vector <string> keywordClasses;
+
+ vector <RegexElement*> regex;
+
+ KeywordMap delimiterPrefixes;
+
+ EmbedLangDelimMap exitDelimiters;
+
+ // saves if delimiter pair consists of the same delimiter symbol
+ map <int, bool> delimiterDistinct;
+
+ map <string, int> delimiterPair;
+
+ // keywords are not case sensitive if set
+ bool ignoreCase,
+
+ // highlighting is disabled
+ disableHighlighting,
+
+ // Escape sequences are allowed outrside of strings
+ allowExtEscape,
+
+ // allow nested multi line comment blocks
+ allowNestedComments,
+
+ // single line comments have to start in coloumn 1 if set
+ fullLineComment,
+
+ // code formatting is enabled if set
+ reformatCode;
+
+ // character which is prefix of raw string (c#)
+ unsigned char rawStringPrefix,
+
+ //character which continues curreent style on next line
+ continuationChar;
+
+ /* reset members */
+ void reset();
+
+ // add a symbol sequence to the symbolStream
+ void addSimpleSymbol ( stringstream& symbolStream, State state,
+ const string& paramValue );
+
+ void addSymbol ( stringstream& symbolStream,
+ State stateBegin,
+ State stateEnd,
+ bool isDelimiter,
+ const string& paramValue,
+ unsigned int classID=0 );
+
+ // add a delimiter symbol sequence to the symbolStream
+ void addDelimiterSymbol ( stringstream& symbolStream,
+ State stateBegin, State stateEnd,
+ const string& paramValue,
+ unsigned int classID=0 );
+
+ void addDelimiterRegex ( stringstream& symbolStream,
+ State stateBegin, State stateEnd,
+ const string& paramValue, const string& langName);
+
+
+
+ //set flag if paramValue is defined
+ void getFlag ( string& paramValue, bool& flag );
+
+ void getSymbol ( const string& paramValue, unsigned char& symbol );
+
+ // generate a unique class ID of the class name
+ unsigned int generateNewKWClass ( const string& newClassName );
+
+ // add keywords to the given class
+ void addKeywords ( const string &kwList,State stateBegin, State stateEnd, int classID );
+
+ struct RegexDef extractRegex ( const string &paramValue );
+
+ Pattern * reDefPattern;
+
+ };
+
+
+ /**\brief Association of a regex with a state description
+
+ A RegexElement associates a regular expression with the state information
+ (opening and closing state, pattern, keyword class, keyword group id, language name)
+ */
+ class RegexElement
+ {
+ public:
+ RegexElement()
+ :open ( STANDARD ), end ( STANDARD ), rePattern ( NULL ), kwClass ( 0 ),capturingGroup ( -1 ), langName()
+ {
+ }
+
+ RegexElement ( State oState, State eState, Pattern *re, unsigned int cID=0, int group=-1, const string& name="" ) :
+ open ( oState ), end ( eState ), rePattern ( re ), kwClass ( cID ), capturingGroup ( group ), langName(name)
+ {
+ // cerr << "new re element "<< rePattern->getPattern() <<" open: "<<open<<" end "<<end<<"\n";
+ }
+
+ ~RegexElement() { if ( rePattern ) delete rePattern; }
+
+ State open, ///< opening state
+ end; ///< closing state
+ Pattern *rePattern; ///< regex pattern
+ unsigned int kwClass; ///< keyword class
+ int capturingGroup; ///< capturing group ID
+ string langName; ///< language name
+
+ private:
+ RegexElement (const RegexElement& rhs){
+ // does not work because Pattern misses copy constructor
+ /*open=rhs.open;
+ end=rhs.end;
+ kwClass=rhs.kwClass;
+ capturingGroup=rhs.capturingGroup;
+ Pattern *pOrig=rePattern;
+ rePattern=new Pattern(*rhs.rePattern);
+ delete pOrig;*/
+ }
+ RegexElement& operator=(const RegexElement& rhs){
+ // does not work because Pattern misses copy constructor
+ /*open=rhs.open;
+ end=rhs.end;
+ kwClass=rhs.kwClass;
+ capturingGroup=rhs.capturingGroup;
+ Pattern *pOrig=rePattern;
+ rePattern=new Pattern(*rhs.rePattern);
+ delete pOrig;
+ */
+ return *this;
+ }
+ };
+
+ /**\brief Association of a regex and its relevant capturing group
+ */
+ struct RegexDef
+ {
+ RegexDef() :capturingGroup ( -1 ) {}
+ string reString; ///< regex string
+ int capturingGroup; ///< capturing group which should be recognized as token
+ };
+
+}
+#endif
diff --git a/support/highlight/src/core/latexgenerator.cpp b/support/highlight/src/core/latexgenerator.cpp
new file mode 100644
index 0000000000..3508d790be
--- /dev/null
+++ b/support/highlight/src/core/latexgenerator.cpp
@@ -0,0 +1,335 @@
+/***************************************************************************
+ LatexCode.cpp - description
+ -------------------
+ begin : Mit Jul 24 2002
+ copyright : (C) 2002 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "latexgenerator.h"
+
+namespace highlight
+{
+
+ LatexGenerator::LatexGenerator()
+ : CodeGenerator ( LATEX ),
+ replaceQuotes ( false ),
+ disableBabelShortHand ( false ),
+ prettySymbols ( false )
+ {
+ // avoid "Underfull \hbox (badness 10000)" warnings
+ newLineTag = "\\\\\n";
+ longLineTag = "\\hspace*{\\fill}" + newLineTag;
+ spacer = "\\ ";
+ maskWs=true;
+ maskWsBegin = "\\hlstd{";
+ maskWsEnd = "}";
+ excludeWs=true;
+ styleCommentOpen="%";
+ }
+
+ LatexGenerator::~LatexGenerator()
+ {}
+
+ void LatexGenerator::printBody()
+ {
+ *out << "\\noindent\n" ;
+ if ( ! this->getBaseFont().empty() )
+ *out << "\\" << this->getBaseFont() << "\n" ;
+ else
+ *out << "\\ttfamily\n";
+ if ( ! this->getBaseFontSize().empty() )
+ *out << "\\" << this->getBaseFontSize() << "\n" ;
+ if ( disableBabelShortHand )
+ *out << "\\shorthandoff{\"}\n";
+
+ processRootState();
+
+ *out << "\\mbox{}\n"
+ << "\\normalfont\n";
+ if ( ! this->getBaseFontSize().empty() )
+ *out << "\\normalsize\n" ;
+ if ( disableBabelShortHand )
+ *out << "\\shorthandon{\"}\n";
+ }
+
+ string LatexGenerator::getHeader()
+ {
+ ostringstream os;
+
+ os << "\\documentclass{article}\n"
+ << "\\usepackage{color}\n"
+ << "\\usepackage{alltt}\n";
+
+ if ( StringTools::change_case ( encoding ) =="utf-8" )
+ {
+ os << "\\usepackage{ucs}\n\\usepackage[utf8x]{inputenc}\n";
+ }
+ else if ( encodingDefined() )
+ {
+ os << "\\usepackage[latin1]{inputenc}\n";
+ }
+
+ //needed for Righttorque symbol
+ if ( preFormatter.isEnabled() )
+ {
+ os << "\\usepackage{marvosym}\n";
+ }
+
+ if ( langInfo.highlightingEnabled() )
+ {
+ if ( includeStyleDef )
+ {
+ os << "\n"<<getStyleDefinition();
+ os << CodeGenerator::readUserStyleDef();
+ }
+ else
+ {
+ os << "\n\\input {"
+ << getStyleOutputPath()
+ << "}\n";
+ }
+ }
+
+ os << "\n\\title{" << docTitle << "}\n"
+ << "\\begin{document}\n"
+ << "\\pagecolor{bgcolor}\n";
+
+ if ( prettySymbols )
+ {
+ os<<"\\newsavebox{\\hlboxopenbrace}\n"
+ <<"\\newsavebox{\\hlboxclosebrace}\n"
+ <<"\\newsavebox{\\hlboxlessthan}\n"
+ <<"\\newsavebox{\\hlboxgreaterthan}\n"
+ <<"\\newsavebox{\\hlboxdollar}\n"
+ <<"\\newsavebox{\\hlboxunderscore}\n"
+ <<"\\newsavebox{\\hlboxand}\n"
+ <<"\\newsavebox{\\hlboxhash}\n"
+ <<"\\newsavebox{\\hlboxat}\n"
+ <<"\\newsavebox{\\hlboxbackslash}\n"
+ <<"\\newsavebox{\\hlboxpercent}\n"
+ <<"\\newsavebox{\\hlboxhat}\n"
+
+ <<"\\setbox\\hlboxopenbrace=\\hbox{\\verb.{.}\n"
+ <<"\\setbox\\hlboxclosebrace=\\hbox{\\verb.}.}\n"
+ <<"\\setbox\\hlboxlessthan=\\hbox{\\verb.<.}\n"
+ <<"\\setbox\\hlboxgreaterthan=\\hbox{\\verb.>.}\n"
+
+ <<"\\setbox\\hlboxdollar=\\hbox{\\verb.$.}\n"
+ <<"\\setbox\\hlboxunderscore=\\hbox{\\verb._.}\n"
+ <<"\\setbox\\hlboxand=\\hbox{\\verb.&.}\n"
+ <<"\\setbox\\hlboxhash=\\hbox{\\verb.#.}\n"
+ <<"\\setbox\\hlboxat=\\hbox{\\verb.@.}\n"
+ <<"\\setbox\\hlboxbackslash=\\hbox{\\verb.\\.}\n"
+ <<"\\setbox\\hlboxpercent=\\hbox{\\verb.\\%.}\n"
+ <<"\\setbox\\hlboxhat=\\hbox{\\verb.^.}\n"
+
+ <<"\\def\\urltilda{\\kern -.15em\\lower .7ex\\hbox{\\~{}}\\kern .04em}\n";
+ }
+
+ return os.str();
+ }
+
+ string LatexGenerator::getFooter()
+ {
+ ostringstream os;
+ os << "\\end {document}\n"
+ << "(* LaTeX generated by highlight "
+ << HIGHLIGHT_VERSION
+ << ", "
+ << HIGHLIGHT_URL
+ << " *)\n";
+ return os.str();
+ }
+
+
+ void LatexGenerator::initOutputTags(){
+ openTags.push_back ( "\\hlstd{" );
+ openTags.push_back ( "\\hlstr{" );
+ openTags.push_back ( "\\hlnum{" );
+ openTags.push_back ( "\\hlslc{" );
+ openTags.push_back ( "\\hlcom{" );
+ openTags.push_back ( "\\hlesc{" );
+ openTags.push_back ( "\\hldir{" );
+ openTags.push_back ( "\\hldstr{" );
+ openTags.push_back ( "\\hlline{" );
+ openTags.push_back ( "\\hlsym{" );
+
+ for ( int i=0;i<NUMBER_BUILTIN_STATES; i++ )
+ {
+ closeTags.push_back ( "}" );
+ }
+ }
+
+ string LatexGenerator::getAttributes ( const string & elemName,
+ const ElementStyle &elem )
+ {
+ ostringstream s;
+ s << "\\newcommand{\\hl"
+ << elemName
+ << "}[1]{\\textcolor[rgb]{"
+ << elem.getColour().getRed ( LATEX ) << ","
+ << elem.getColour().getGreen ( LATEX ) << ","
+ << elem.getColour().getBlue ( LATEX )
+ << "}{";
+
+ if ( elem.isBold() )
+ s << "\\bf{";
+ if ( elem.isItalic() )
+ s << "\\it{";
+
+ s <<"#1";
+
+ if ( elem.isBold() )
+ s << "}";
+ if ( elem.isItalic() )
+ s << "}";
+
+ s <<"}}\n";
+ return s.str();
+ }
+
+
+ string LatexGenerator::getNewLine()
+ {
+ string nl;
+
+ // set wrapping arrow if previous line was wrapped
+ if ( preFormatter.isWrappedLine ( lineNumber-1 ) )
+ {
+ nl = "\\Righttorque";
+ }
+ nl += ( showLineNumbers ) ? newLineTag:longLineTag;
+ return nl;
+ }
+
+ string LatexGenerator::maskCharacter ( unsigned char c )
+ {
+ switch ( c )
+ {
+ case ' ':
+ return spacer;
+ break;
+
+ case '<' :
+ return prettySymbols ? "\\usebox{\\hlboxlessthan}" : "$<$";
+ break;
+ case '>' :
+ return prettySymbols ? "\\usebox{\\hlboxgreaterthan}" : "$>$";
+ break;
+ case '{':
+ return prettySymbols ? "\\usebox{\\hlboxopenbrace}" : "\\{";
+ break;
+ case '}':
+ return prettySymbols ? "\\usebox{\\hlboxclosebrace}" : "\\}";
+ break;
+
+ case '&':
+ case '$':
+ case '#':
+ case '%':
+ {
+ string m ( "\\" );
+ m += c;
+ return m;
+ }
+ break;
+ case '\"':
+ return ( replaceQuotes ) ?"\\dq{}":"\"";
+ break;
+ case '_':
+ return "\\textunderscore ";
+ break;
+ case '^':
+ return "\\textasciicircum ";
+ break;
+ case '\\':
+ return "$\\backslash$";
+ break;
+ case '~':
+ return prettySymbols ? "\\urltilda " : "$\\sim$";
+ break;
+ case '|':
+ return "\\textbar ";
+ break;
+ // avoid latex compilation failure if [ or * follows a line break (\\)
+ case '*':
+ case '[':
+ case ']':
+ // avoid "merging" of consecutive '-' chars when included in bold font ( \bf )
+ case '-':
+ {
+ string m ( 1, '{' );
+ m += c;
+ m += '}';
+ return m;
+ }
+ break;
+ default :
+ return string ( 1, c );
+ }
+ }
+
+ string LatexGenerator::getKeywordOpenTag ( unsigned int styleID )
+ {
+ return "\\hl"+langInfo.getKeywordClasses() [styleID]+"{";
+ }
+
+ string LatexGenerator::getKeywordCloseTag ( unsigned int styleID )
+ {
+ return "}";
+ }
+
+ string LatexGenerator::getStyleDefinition()
+ {
+ if ( styleDefinitionCache.empty() )
+ {
+ ostringstream os;
+ os << getAttributes ( STY_NAME_STD, docStyle.getDefaultStyle() );
+ os << getAttributes ( STY_NAME_NUM, docStyle.getNumberStyle() );
+ os << getAttributes ( STY_NAME_ESC, docStyle.getEscapeCharStyle() );
+ os << getAttributes ( STY_NAME_STR, docStyle.getStringStyle() );
+ os << getAttributes ( STY_NAME_DST, docStyle.getDirectiveStringStyle() );
+ os << getAttributes ( STY_NAME_SLC, docStyle.getSingleLineCommentStyle() );
+ os << getAttributes ( STY_NAME_COM, docStyle.getCommentStyle() );
+ os << getAttributes ( STY_NAME_DIR, docStyle.getDirectiveStyle() );
+ os << getAttributes ( STY_NAME_SYM, docStyle.getSymbolStyle() );
+ os << getAttributes ( STY_NAME_LIN, docStyle.getLineStyle() );
+
+ KeywordStyles styles = docStyle.getKeywordStyles();
+ for ( KSIterator it=styles.begin(); it!=styles.end(); it++ )
+ {
+ os << getAttributes ( it->first, it->second );
+ }
+ os << "\\definecolor{bgcolor}{rgb}{"
+ << docStyle.getBgColour().getRed ( LATEX ) << ","
+ << docStyle.getBgColour().getGreen ( LATEX ) << ","
+ << docStyle.getBgColour().getBlue ( LATEX )
+ << "}\n";
+
+ styleDefinitionCache=os.str();
+ }
+ return styleDefinitionCache;
+ }
+
+
+}
diff --git a/support/highlight/src/core/latexgenerator.h b/support/highlight/src/core/latexgenerator.h
new file mode 100644
index 0000000000..a1e56c55e4
--- /dev/null
+++ b/support/highlight/src/core/latexgenerator.h
@@ -0,0 +1,118 @@
+/***************************************************************************
+ latexgenerator.h - description
+ -------------------
+ begin : Mit Jul 24 2002
+ copyright : (C) 2002 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef LATEXGENERATOR_H
+#define LATEXGENERATOR_H
+
+#include <string>
+#include <iostream>
+#include <sstream>
+
+#include "codegenerator.h"
+#include "version.h"
+#include "charcodes.h"
+
+
+namespace highlight
+{
+
+ /**
+ \brief This class generates LaTeX.
+
+ It contains information about the resulting document structure (document
+ header and footer), the colour system, white space handling and text
+ formatting attributes.
+
+ * @author Andre Simon
+ */
+
+ class LatexGenerator : public highlight::CodeGenerator
+ {
+ public:
+ LatexGenerator();
+ ~LatexGenerator();
+
+ /** set replace quotes flag
+ \param b flag
+ */
+ void setLATEXReplaceQuotes ( bool b ) { replaceQuotes = b;}
+
+ /** set disable babel shorthand flag
+ \param b flag
+ */
+ void setLATEXNoShorthands ( bool b ) { disableBabelShortHand = b; }
+
+ /** set pretty symbols flag
+ \param b flag
+ */
+ void setLATEXPrettySymbols ( bool b ) { prettySymbols = b; }
+
+ private:
+
+ /** prints document header
+ */
+ string getHeader();
+
+ /** Prints document footer*/
+ string getFooter();
+
+ /** Prints document body*/
+ void printBody();
+
+ /** initialize tags in specific format according to colouring information provided in DucumentStyle */
+ void initOutputTags();
+
+ string styleDefinitionCache;
+ string longLineTag;
+
+ /** \return escaped character*/
+ virtual string maskCharacter ( unsigned char );
+
+ /**\return text formatting attributes in LaTeX format */
+ string getAttributes ( const string & elemName,
+ const ElementStyle & elem );
+
+ /** test if double quotes should be replaced by \dq{} */
+ bool replaceQuotes;
+
+ /** test if Babel shorthand for " should be disabled */
+ bool disableBabelShortHand;
+
+ /** test if symbols like <,>,{,},~ should be replaced by nicer definitions */
+ bool prettySymbols;
+
+ string getNewLine();
+
+ string getStyleDefinition();
+
+ string getKeywordOpenTag ( unsigned int styleID );
+ string getKeywordCloseTag ( unsigned int styleID );
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/platform_fs.cpp b/support/highlight/src/core/platform_fs.cpp
new file mode 100644
index 0000000000..2719bf7a69
--- /dev/null
+++ b/support/highlight/src/core/platform_fs.cpp
@@ -0,0 +1,339 @@
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "platform_fs.h"
+
+// includes for recursive getFileNames() function
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <dirent.h>
+#include <errno.h>
+#include <sys/stat.h>
+#ifdef __VMS
+#include <unixlib.h>
+#include <rms.h>
+#include <ssdef.h>
+#include <stsdef.h>
+#include <lib$routines.h>
+#include <starlet.h>
+#endif /* __VMS */
+#endif
+
+#include <algorithm>
+#include <iostream>
+#include <errno.h>
+
+using namespace std;
+
+namespace Platform
+{
+
+#ifdef _WIN32
+#include <windows.h>
+ const char pathSeparator = '\\';
+ std::string getAppPath()
+ {
+ char pathAndName[MAX_PATH], path[MAX_PATH], drive[3];
+ GetModuleFileName ( NULL, ( wchar_t* ) pathAndName, MAX_PATH );
+ _splitpath ( pathAndName, drive, path, 0, 0 );
+ return std::string ( drive ) +path;
+ }
+#else
+ const char pathSeparator = '/';
+
+ std::string getAppPath()
+ {
+ return "";
+ }
+#endif
+
+ bool getDirectoryEntries ( vector<string> &fileList,
+ string wildcard,
+ bool recursiveSearch )
+ {
+ if ( !wildcard.empty() )
+ {
+ string directory_path;
+ string::size_type Pos = wildcard.find_last_of ( pathSeparator );
+ if ( Pos == string::npos )
+ {
+ directory_path = ".";
+ }
+ else
+ {
+ directory_path = wildcard.substr ( 0, Pos + 1 );
+ wildcard = wildcard.substr ( Pos + 1 );
+ }
+
+ /* old method using dirstream:
+ dirstr::dirstream str( directory_path.c_str(),
+ #ifdef USE_FN_MATCH
+ dirstr::pred_f(FnMatcher(wildcard.c_str(), 0)),
+ #else
+ dirstr::pattern_f(wildcard.c_str()),
+ #endif
+ (recursiveSearch)?dirstr::recursive_yes:dirstr::recursive_no);
+ for(string entry; str >> entry;) {
+ fileList.push_back(dirstr::full_path(entry));
+ //cerr << "1: "<<dirstr::full_path(entry)<<"\n";
+ }
+ */
+
+ // new method using getFileNames:
+ getFileNames ( directory_path, wildcard, fileList );
+ }
+ return ! ( fileList.empty() );
+ }
+
+
+#ifdef _WIN32 // Windows specific
+
+ /**
+ * WINDOWS function to resolve wildcards and recurse into sub directories.
+ * The fileName vector is filled with the path and names of files to process.
+ *
+ * @param directory The path of the directory to be processed.
+ * @param wildcard The wildcard to be processed (e.g. *.cpp).
+ * @param filenam An empty vector which will be filled with the path and names of files to process.
+ */
+ void getFileNames ( const string &directory,const string &wildcard, vector<string> &fileName )
+ {
+ vector<string> subDirectory; // sub directories of directory
+ WIN32_FIND_DATA FindFileData; // for FindFirstFile and FindNextFile
+
+ // Find the first file in the directory
+ string firstFile = directory + "\\*";
+ HANDLE hFind = FindFirstFile ( firstFile.c_str(), &FindFileData );
+
+ if ( hFind == INVALID_HANDLE_VALUE )
+ return;
+ //error("Cannot open directory", directory.c_str());
+
+ // save files and sub directories
+ do
+ {
+ // skip hidden or read only
+ if ( FindFileData.cFileName[0] == '.'
+ || ( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN )
+ || ( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY ) )
+ continue;
+
+ // if a sub directory and recursive, save sub directory
+ if ( ( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) && true /*g_isRecursive*/ )
+ {
+ string subDirectoryPath = directory + pathSeparator + FindFileData.cFileName;
+ //if (isPathExclued(subDirectoryPath))
+ //{
+ // if (!g_isQuiet)
+ // cout << "exclude " << subDirectoryPath.substr(g_mainDirectoryLength) << endl;
+ //}
+ //else
+ subDirectory.push_back ( subDirectoryPath );
+ continue;
+ }
+
+ // save the file name
+ string filePathName = directory + pathSeparator + FindFileData.cFileName;
+ // check exclude before wildcmp to avoid "unmatched exclude" error
+ //bool isExcluded = isPathExclued(filePathName);
+ // save file name if wildcard match
+ if ( wildcmp ( wildcard.c_str(), FindFileData.cFileName ) )
+ {
+ //if (isExcluded)
+ // cout << "exclude " << filePathName.substr(g_mainDirectoryLength) << endl;
+ //else
+ fileName.push_back ( filePathName );
+ }
+ }
+ while ( FindNextFile ( hFind, &FindFileData ) != 0 );
+
+ // check for processing error
+ FindClose ( hFind );
+ DWORD dwError = GetLastError();
+ if ( dwError != ERROR_NO_MORE_FILES )
+ return;
+ //error("Error processing directory", directory.c_str());
+
+ // recurse into sub directories
+ // if not doing recursive subDirectory is empty
+ for ( unsigned i = 0; i < subDirectory.size(); i++ )
+ {
+// cout << "directory " << subDirectory[i] << endl;
+ getFileNames ( subDirectory[i], wildcard, fileName );
+ continue;
+ }
+
+ return;
+ }
+
+#else // not _WIN32
+
+ /**
+ * LINUX function to resolve wildcards and recurse into sub directories.
+ * The fileName vector is filled with the path and names of files to process.
+ *
+ * @param directory The path of the directory to be processed.
+ * @param wildcard The wildcard to be processed (e.g. *.cpp).
+ * @param filenam An empty vector which will be filled with the path and names of files to process.
+ */
+ void getFileNames ( const string &directory,const string &wildcard, vector<string> &fileName )
+ {
+ struct dirent *entry; // entry from readdir()
+ struct stat statbuf; // entry from stat()
+ vector<string> subDirectory; // sub directories of this directory
+
+ // errno is defined in <errno.h> and is set for errors in opendir, readdir, or stat
+ errno = 0;
+
+ DIR *dp = opendir ( directory.c_str() );
+ if ( errno )
+ return;
+ //error("Cannot open directory", directory.c_str());
+
+ // save the first fileName entry for this recursion
+ const unsigned firstEntry = fileName.size();
+
+ // save files and sub directories
+ while ( ( entry = readdir ( dp ) ) != NULL )
+ {
+ // get file status
+ string entryFilepath = directory + pathSeparator + entry->d_name;
+ stat ( entryFilepath.c_str(), &statbuf );
+ if ( errno )
+ return;
+ //error("Error getting file status in directory", directory.c_str());
+
+ // skip hidden or read only
+ if ( entry->d_name[0] == '.' || ! ( statbuf.st_mode & S_IWUSR ) )
+ continue;
+ // if a sub directory and recursive, save sub directory
+ if ( S_ISDIR ( statbuf.st_mode ) && /*g_isRecursive*/ true ) ///TODO
+ {
+ // if (isPathExclued(entryFilepath))
+ // cout << "exclude " << entryFilepath.substr(g_mainDirectoryLength) << endl;
+ // else
+ subDirectory.push_back ( entryFilepath );
+ continue;
+ }
+
+ // if a file, save file name
+ if ( S_ISREG ( statbuf.st_mode ) )
+ {
+ // check exclude before wildcmp to avoid "unmatched exclude" error
+ // bool isExcluded = isPathExclued(entryFilepath);
+ // save file name if wildcard match
+ if ( wildcmp ( wildcard.c_str(), entry->d_name ) )
+ {
+ // if (isExcluded)
+ // cout << "exclude " << entryFilepath.substr(g_mainDirectoryLength) << endl;
+ // else
+ fileName.push_back ( entryFilepath );
+ }
+ }
+ }
+ closedir ( dp );
+
+ if ( errno )
+ return;
+ //error("Error reading directory", directory.c_str());
+
+ // sort the current entries for fileName
+ if ( firstEntry < fileName.size() )
+ sort ( &fileName[firstEntry], &fileName[fileName.size() ] );
+
+ // recurse into sub directories
+ // if not doing recursive, subDirectory is empty
+ if ( subDirectory.size() > 1 )
+ sort ( subDirectory.begin(), subDirectory.end() );
+ for ( unsigned i = 0; i < subDirectory.size(); i++ )
+ {
+ getFileNames ( subDirectory[i], wildcard, fileName );
+ continue;
+ }
+
+ return;
+ }
+
+#endif
+
+// From The Code Project http://www.codeproject.com/string/wildcmp.asp
+// Written by Jack Handy - jakkhandy@hotmail.com
+// Modified to compare case insensitive for Windows (the LC macro)
+ int wildcmp ( const char *wild, const char *data )
+ {
+ const char *cp = NULL, *mp = NULL;
+ bool cmpval;
+
+ while ( ( *data ) && ( *wild != '*' ) )
+ {
+#ifdef _WIN32
+ cmpval = ( tolower ( *wild ) != tolower ( *data ) ) && ( *wild != '?' );
+#else
+ cmpval = ( *wild != *data ) && ( *wild != '?' );
+#endif
+
+ if ( cmpval )
+ {
+ return 0;
+ }
+ wild++;
+ data++;
+ }
+
+ while ( *data )
+ {
+ if ( *wild == '*' )
+ {
+ if ( !*++wild )
+ {
+ return 1;
+ }
+ mp = wild;
+ cp = data+1;
+ }
+ else
+ {
+#ifdef _WIN32
+ cmpval = ( tolower ( *wild ) == tolower ( *data ) || ( *wild == '?' ) );
+#else
+ cmpval = ( *wild == *data ) || ( *wild == '?' );
+#endif
+
+ if ( cmpval )
+ {
+ wild++;
+ data++;
+ }
+ else
+ {
+ wild = mp;
+ data = cp++;
+ }
+ }
+ }
+
+ while ( *wild == '*' )
+ {
+ wild++;
+ }
+ return !*wild;
+ }
+
+}
diff --git a/support/highlight/src/core/platform_fs.h b/support/highlight/src/core/platform_fs.h
new file mode 100644
index 0000000000..63f36a455c
--- /dev/null
+++ b/support/highlight/src/core/platform_fs.h
@@ -0,0 +1,68 @@
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef PLATFORM_FS__H__INCLUDED
+#define PLATFORM_FS__H__INCLUDED
+
+#include <string>
+#include <iostream>
+#include <vector>
+/*
+#ifdef USE_FN_MATCH
+ #include <fnmatch.h>
+#endif
+*/
+
+namespace Platform
+{
+ extern const char pathSeparator;
+
+ std::string getAppPath();
+
+ /** \param fileList Vector where found entries will be stored
+ \param wildcard Directory path and wildcard
+ \param recursiveSearch Test if directory should be searched recursively */
+ bool getDirectoryEntries ( std::vector<std::string> &fileList,
+ std::string wildcard,
+ bool recursiveSearch=false );
+
+ void getFileNames ( const std::string &directory,const std::string &wildcard,
+ std::vector<std::string> &fileName );
+
+ int wildcmp ( const char *wild, const char *data );
+
+ /*
+ #ifdef USE_FN_MATCH
+ struct FnMatcher
+ {
+ FnMatcher(const char* pattern, int flags)
+ : pattern_(pattern)
+ , flags_(flags)
+ {}
+ bool operator()(const std::string& e) const {
+ return ! ::fnmatch(pattern_, e.c_str(), flags_);
+ }
+ private:
+ const char* pattern_;
+ int flags_;
+ };
+ #endif
+ */
+
+}
+#endif
diff --git a/support/highlight/src/core/preformatter.cpp b/support/highlight/src/core/preformatter.cpp
new file mode 100644
index 0000000000..88ef5293f5
--- /dev/null
+++ b/support/highlight/src/core/preformatter.cpp
@@ -0,0 +1,206 @@
+/***************************************************************************
+ PreFormatter.cpp - description
+ -------------------
+ begin : Mo Jan 03 2005
+ copyright : (C) 2005-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "preformatter.h"
+
+#include <iostream>
+#include "stringtools.h"
+
+namespace highlight
+{
+
+ const std::string PreFormatter::LB_CHARS = " \t[](){}-+<>.:,;";
+ const std::string PreFormatter::WS_CHARS = " \n\r\t";
+ const std::string PreFormatter::INDENT_MARKERS = "{(=";
+
+ PreFormatter::PreFormatter() :
+ maxLineLength ( 80 ),
+ index ( 0 ),
+ numberSpaces ( 0 ),
+ lineNumber ( 0 ),
+ wsPrefixLength ( string::npos ),
+ hasMore ( false ),
+ indentAfterOpenBraces ( true ),
+ redefineWsPrefix ( false ),
+ wrapLines ( false ),
+ replaceTabs ( false )
+ {
+ }
+
+ PreFormatter::~PreFormatter()
+ {
+ }
+
+ bool PreFormatter::hasMoreLines()
+ {
+ return hasMore;
+ }
+
+ bool PreFormatter::indentCode()
+ {
+ return indentAfterOpenBraces;
+ }
+
+ void PreFormatter::setLine ( const std::string& newLine )
+ {
+
+ line=newLine;
+
+ if ( replaceTabs && numberSpaces )
+ {
+ size_t tabPos=line.find ( '\t' );
+ while ( tabPos!=string::npos )
+ {
+ line.replace ( tabPos , 1, numberSpaces - ( tabPos % numberSpaces ) , ' ' );
+ tabPos = line.find ( '\t', tabPos+1 );
+ }
+ }
+
+ if ( wrapLines )
+ {
+ wsPrefix.clear();
+ index=0;
+ wsPrefixLength=string::npos;
+ hasMore=true;
+ redefineWsPrefix=false;
+ }
+ }
+
+ std::string PreFormatter::getNextLine()
+ {
+
+ if ( !wrapLines )
+ {
+ hasMore = false;
+ return line;
+ }
+
+ ++lineNumber;
+
+ if ( !index && line.length() > maxLineLength ) // erster Durchlauf...
+ {
+ // wenn moeglich an oeffnender Klammer oder Geichheitszeichen ausrichten
+ if ( indentAfterOpenBraces )
+ {
+ wsPrefixLength=line.find_first_of ( INDENT_MARKERS );
+ }
+ // sonst die Einrckung der Originalzeile beibehalten
+ if ( wsPrefixLength==string::npos || wsPrefixLength-index>maxLineLength )
+ {
+ wsPrefixLength=line.find_first_not_of ( WS_CHARS );
+ }
+ else
+ {
+ // wsPrefix in allen neu umgebrochenen Zeilen durch Spaces ersetzen
+ redefineWsPrefix=true;
+ // Position hinter oeffnende Klammer springen
+ wsPrefixLength=line.find_first_not_of ( WS_CHARS,wsPrefixLength+1 );
+ }
+
+ if ( wsPrefixLength!=string::npos )
+ {
+ index = wsPrefixLength;
+ // Falls Anzahl der Whitespaces am beginn der ersten zeile groesser
+ // als Max. Zeilenlaenge, Whitespaces verwerfen
+ if ( wsPrefixLength>maxLineLength )
+ {
+ wsPrefixLength=0;
+ return string();
+ }
+ else
+ {
+ wsPrefix=line.substr ( 0, wsPrefixLength );
+ }
+ }
+ // Zeile enthaelt nur Whitespace; verwerfen
+ else
+ {
+ hasMore= false;
+ return string();
+ }
+ }
+ else
+ {
+ if ( redefineWsPrefix )
+ {
+ wsPrefix.clear();
+ wsPrefix.append ( wsPrefixLength, ' ' );
+ }
+ redefineWsPrefix=false;
+ }
+
+ string resultString;
+
+ // Position, ab der rueckwaerts nach Umbruchmglichkeit gesucht wird
+ unsigned int searchEndPos = maxLineLength - wsPrefixLength;
+
+ // letztes Teilstueck der Zeile ausgeben; Parsen beenden
+ if ( line.length()-index < searchEndPos )
+ {
+ hasMore=false;
+ resultString= ( index>0 ) ? wsPrefix + line.substr ( index ) : line.substr ( index );
+ return resultString;
+ }
+
+ // Umbrechposition suchen
+ size_t lbPos = line.find_last_of ( LB_CHARS, index+searchEndPos );
+ if ( lbPos <= index || lbPos == string::npos )
+ {
+ // nichts gefunden, hart umbrechen
+ lbPos = index + searchEndPos;
+ }
+ // Einrckung der Originalzeile erhalten
+ resultString+=wsPrefix;
+ // Neue Zeile erzeugen
+ resultString += line.substr ( index, lbPos-index+1 );
+
+ // Whitespace am neuen Zeilenbeginn ignorieren, ausser beim ersten Durchlauf
+ size_t newIndex=line.find_first_not_of ( WS_CHARS, lbPos+1 );
+ index= ( newIndex!=string::npos ) ?newIndex:line.length();
+
+ hasMore=index!=line.length(); // unnoetigen Leerstring vermeiden
+
+ if ( hasMore ) wrappedLines.insert ( lineNumber ); // diese Zeile wurde umgebrochen
+
+ return resultString;
+ }
+
+ void PreFormatter::setWrapLineLength ( unsigned int maxLineLength )
+ {
+ this->maxLineLength = maxLineLength;
+ }
+ void PreFormatter::setWrapIndentBraces ( bool indentAfterOpenBraces )
+ {
+ this->indentAfterOpenBraces = indentAfterOpenBraces;
+ }
+
+ void PreFormatter::setNumberSpaces ( unsigned int num )
+ {
+ numberSpaces = num;
+ }
+
+}
diff --git a/support/highlight/src/core/preformatter.h b/support/highlight/src/core/preformatter.h
new file mode 100644
index 0000000000..4afcb28464
--- /dev/null
+++ b/support/highlight/src/core/preformatter.h
@@ -0,0 +1,150 @@
+/***************************************************************************
+ PreFormatter.cpp - description
+ -------------------
+ begin : Mo Jan 03 2005
+ copyright : (C) 2005-2008 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef PreFormatter_H
+#define PreFormatter_H
+
+#include <string>
+#include <set>
+
+namespace highlight
+{
+
+ /** \brief Class which provides intelligent line wrapping.
+ * @author Andre Simon
+ */
+
+ class PreFormatter
+ {
+ public:
+
+ PreFormatter();
+
+ ~PreFormatter();
+
+ /**
+ Set wrapping mode
+ \param wrap set to true if long lines should be wrapped
+ */
+ void setWrap ( bool wrap ) {wrapLines = wrap;}
+
+ /**
+ Replace tabs by spaces
+ \param replTabs set to true if tabs should be replaced by spaces
+ */
+ void setReplaceTabs ( bool replTabs ) {replaceTabs = replTabs;}
+
+ /**
+ \return True if current line can be wrapped again
+ */
+ bool hasMoreLines();
+
+ /**
+ Sets new line to be wrapped
+ \param newline New line
+ */
+ void setLine ( const std::string & newline );
+
+ /**
+ The method will indent function calls and statements
+ \return Next line
+ */
+ std::string getNextLine();
+
+ /**
+ \return True if lines following open braces should be indented
+ */
+ bool indentCode();
+
+ /**
+ Maximum line length
+ \param maxlength max. length of output lines
+ */
+ void setWrapLineLength ( unsigned int maxlength );
+
+ /**
+ Indentation mode
+ \param indentAfterOpenBraces set true if lines should be indented after braces
+ */
+ void setWrapIndentBraces ( bool indentAfterOpenBraces=true );
+
+ /**
+ Number of spaces
+ \param num number of spaces which replace a tab
+ */
+ void setNumberSpaces ( unsigned int num );
+
+ /**
+ \return true if preformatting is enabled
+ */
+ bool isEnabled()
+ {
+ return wrapLines || replaceTabs;
+ }
+
+ /**
+ reset preformatting state to use the object with new input data
+ */
+ void reset ()
+ {
+ lineNumber=0;
+ wrappedLines.clear();
+ }
+
+ /**
+ \param lineNumber line number
+ \return true if input line linenumber was wrapped
+ */
+ bool isWrappedLine ( int lineNumber )
+ {
+ return wrappedLines.count ( lineNumber );
+ }
+
+ private:
+
+ unsigned int maxLineLength;
+
+ std::string line, wsPrefix;
+ unsigned int index;
+ unsigned int numberSpaces;
+ unsigned int lineNumber;
+ size_t wsPrefixLength;
+ bool hasMore, indentAfterOpenBraces;
+ bool redefineWsPrefix;
+ bool wrapLines, replaceTabs;
+
+ std::set<int> wrappedLines;
+
+ static const std::string LB_CHARS;
+ static const std::string WS_CHARS;
+ static const std::string INDENT_MARKERS;
+
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/re/Matcher.cpp b/support/highlight/src/core/re/Matcher.cpp
new file mode 100644
index 0000000000..341bfbd105
--- /dev/null
+++ b/support/highlight/src/core/re/Matcher.cpp
@@ -0,0 +1,178 @@
+#include "Matcher.h"
+#include "Pattern.h"
+
+const int Matcher::MATCH_ENTIRE_STRING = 0x01;
+
+/*
+ Detailed documentation is provided in this class' header file
+
+ @author Jeffery Stuart
+ @since November 2004
+ @version 1.05.01
+*/
+
+Matcher::Matcher(Pattern * pattern, const std::string & text)
+{
+ pat = pattern;
+ str = text;
+ gc = pattern->groupCount;
+ ncgc = -pattern->nonCapGroupCount;
+ flags = 0;
+ matchedSomething = false;
+ starts = new int[gc + ncgc];
+ ends = new int[gc + ncgc];
+ groups = new int[gc + ncgc];
+ groupPos = new int[gc + ncgc];
+ groupIndeces = new int[gc + ncgc];
+ starts = starts + ncgc;
+ ends = ends + ncgc;
+ groups = groups + ncgc;
+ groupPos = groupPos + ncgc;
+ groupIndeces = groupIndeces + ncgc;
+ for (int i = 0; i < gc; ++i) starts[i] = ends[i] = 0;
+}
+Matcher::~Matcher()
+{
+ delete [] (starts - ncgc);
+ delete [] (ends - ncgc);
+ delete [] (groups - ncgc);
+ delete [] (groupIndeces - ncgc);
+ delete [] (groupPos - ncgc);
+}
+void Matcher::clearGroups()
+{
+ int i;
+ lm = 0;
+ for (i = 0; i < gc; ++i) groups[i] = starts[i] = ends[i] = -1;
+ for (i = 1; i <= ncgc; ++i) groups[0 - i] = -1;
+}
+std::string Matcher::replaceWithGroups(const std::string & str)
+{
+ std::string ret = "";
+
+ std::string t = str;
+ while (t.size() > 0)
+ {
+ if (t[0] == '\\')
+ {
+ t = t.substr(1);
+ if (t.size() == 0)
+ {
+ ret += "\\";
+ }
+ else if (t[0] < '0' || t[0] > '9')
+ {
+ ret += t.substr(0, 1);
+ t = t.substr(1);
+ }
+ else
+ {
+ int gn = 0;
+ while (t.size() > 0 && t[0] >= '0' && t[0] <= '9')
+ {
+ gn = gn * 10 + (t[0] - '0');
+ t = t.substr(1);
+ }
+ ret += getGroup(gn);
+ }
+ }
+ else
+ {
+ ret += t.substr(0, 1);
+ t = t.substr(1);
+ }
+ }
+
+ return ret;
+}
+unsigned long Matcher::getFlags() const
+{
+ return flags;
+}
+std::string Matcher::getText() const
+{
+ return str;
+}
+
+bool Matcher::matches()
+{
+ flags = MATCH_ENTIRE_STRING;
+ matchedSomething = false;
+ clearGroups();
+ lm = 0;
+ return pat->head->match(str, this, 0) == (int)str.size();
+}
+bool Matcher::findFirstMatch()
+{
+ starts[0] = 0;
+ flags = 0;
+ clearGroups();
+ start = 0;
+ lm = 0;
+ ends[0] = pat->head->match(str, this, 0);
+ if (ends[0] >= 0)
+ {
+ matchedSomething = true;
+ return 1;
+ }
+ return 0;
+}
+bool Matcher::findNextMatch()
+{
+ int s = starts[0], e = ends[0];
+
+ if (!matchedSomething) return findFirstMatch();
+ if (s == e) ++e;
+ flags = 0;
+ clearGroups();
+
+ starts[0] = e;
+ if (e >= (int)str.size()) return 0;
+ start = e;
+ lm = e;
+ ends[0] = pat->head->match(str, this, e);
+ return ends[0] >= 0;
+}
+std::vector<std::string> Matcher::findAll()
+{
+ std::vector<std::string> ret;
+ reset();
+ while (findNextMatch())
+ {
+ ret.push_back(getGroup());
+ }
+ return ret;
+}
+
+void Matcher::reset()
+{
+ lm = 0;
+ clearGroups();
+ matchedSomething = false;
+}
+
+int Matcher::getStartingIndex(const int groupNum) const
+{
+ if (groupNum < 0 || groupNum >= gc) return -1;
+ return starts[groupNum];
+}
+int Matcher::getEndingIndex(const int groupNum) const
+{
+ if (groupNum < 0 || groupNum >= gc) return -1;
+ return ends[groupNum];
+}
+std::string Matcher::getGroup(const int groupNum) const
+{
+ if (groupNum < 0 || groupNum >= gc) return "";
+ if (starts[groupNum] < 0 || ends[groupNum] < 0) return "";
+ return str.substr(starts[groupNum], ends[groupNum] - starts[groupNum]);
+}
+std::vector<std::string> Matcher::getGroups(const bool includeGroupZero) const
+{
+ int i, start = (includeGroupZero ? 0 : 1);
+ std::vector<std::string> ret;
+
+ for (i = start; i < gc; ++i) ret.push_back(getGroup(i));
+ return ret;
+}
+
diff --git a/support/highlight/src/core/re/Matcher.h b/support/highlight/src/core/re/Matcher.h
new file mode 100644
index 0000000000..8affb5053f
--- /dev/null
+++ b/support/highlight/src/core/re/Matcher.h
@@ -0,0 +1,255 @@
+#ifndef __MATCHER_H__
+#define __MATCHER_H__
+
+#include <string>
+#include <vector>
+
+class Vector;
+class NFANode;
+class NFAStartNode;
+class NFAEndNode;
+class NFAGroupHeadNode;
+class NFAGroupLoopNode;
+class NFAGroupLoopPrologueNode;
+class NFAGroupTailNode;
+class NFALookBehindNode;
+class NFAStartOfLineNode;
+class NFAEndOfLineNode;
+class NFAEndOfMatchNode;
+class NFAReferenceNode;
+class Pattern;
+
+/**
+ A matcher is a non thread-safe object used to scan strings using a given
+ {@link Pattern Pattern} object. Using a <code>Matcher</code> is the preferred
+ method for scanning strings. Matchers are not thread-safe. Matchers require
+ very little dynamic memory, hence one is encouraged to create several
+ instances of a matcher when necessary as opposed to sharing a single instance
+ of a matcher.
+ <p>
+ The most common methods needed by the matcher are <code>matches</code>,
+ <code>findNextMatch</code>, and <code>getGroup</code>. <code>matches</code>
+ and <code>findNextMatch</code> both return success or failure, and further
+ details can be gathered from their documentation.
+ <p>
+ Unlike Java's <code>Matcher</code>, this class allows you to change the string
+ you are matching against. This provides a small optimization, since you no
+ longer need multiple matchers for a single pattern in a single thread.
+ <p>
+ This class also provides an extremely handy method for replacing text with
+ captured data via the <code>replaceWithGroups</code> method. A typical
+ invocation looks like:
+ <pre>
+ char buf[10000];
+ std::string str = "\\5 (user name \\1) uses \\7 for his/her shell and \\6 is their home directory";
+ FILE * fp = fopen("/etc/passwd", "r");
+ Pattern::registerPattern("entry", "[^:]+");
+ Pattern * p = Pattern::compile("^({entry}):({entry}):({entry}):({entry}):({entry}):({entry}):({entry})$",
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pattern::MULTILINE_MATCHING | Pattern::UNIX_LINE_MODE);
+ Matcher * m = p->createMatcher("");
+ while (fgets(buf, 9999, fp))
+ {
+ &nbsp;&nbsp;m->setString(buf);
+ &nbsp;&nbsp;if (m->matches())
+ &nbsp;&nbsp;{
+ &nbsp;&nbsp;&nbsp;&nbsp;printf("%s\n", m->replaceWithGroups(str).c_str());
+ &nbsp;&nbsp;}
+ }
+ fclose(fp);
+
+ </pre>
+ Calling any of the following functions before first calling
+ <code>matches</code>, <code>findFirstMatch</code>, or
+ <code>findNextMatch</code> results in undefined behavior and may cause your
+ program to crash.
+ <code>
+ <ul>
+ <li>replaceWithGroups</code>
+ <li>getStartingIndex</li>
+ <li>getEndingIndex</li>
+ <li>getGroup</li>
+ <li>getGroups</li>
+ </ul>
+ </code>
+ <p>
+ The function <code>findFirstMatch</code> will attempt to find the first match
+ in the input string. The same results can be obtained by first calling
+ <code>reset</code> followed by <code>findNextMatch</code>.
+ <p>
+ To eliminate the necessity of looping through a string to find all the
+ matching substrings, <code>findAll</code> was created. The function will find
+ all matching substrings and return them in a <code>vector</code>. If you need
+ to examine specific capture groups within the substrings, then this method
+ should not be used.
+
+ @author Jeffery Stuart
+ @since March 2003, Stable Since November 2004
+ @version 1.04
+ @memo Mutable object used on instances of a Pattern class
+ */
+class Matcher
+{
+ friend class NFANode;
+ friend class NFAStartNode;
+ friend class NFAEndNode;
+ friend class NFAGroupHeadNode;
+ friend class NFAGroupLoopNode;
+ friend class NFAGroupLoopPrologueNode;
+ friend class NFAGroupTailNode;
+ friend class NFALookBehindNode;
+ friend class NFAStartOfLineNode;
+ friend class NFAEndOfLineNode;
+ friend class NFAEndOfMatchNode;
+ friend class NFAReferenceNode;
+ friend class Pattern;
+ private:
+ /**
+ Creates a new matcher object against <code>text</code> using
+ <code>pattern</code>.
+
+ @param pattern The pattern with which to search
+ @param text The text in which to search
+ */
+ Matcher(Pattern * pattern, const std::string & text);
+ protected:
+ /// The pattern we use to match
+ Pattern * pat;
+ /// The string in which we are matching
+ std::string str;
+ /// The starting point of our match
+ int start;
+ /// An array of the starting positions for each group
+ int * starts;
+ /// An array of the ending positions for each group
+ int * ends;
+ /// An array of private data used by NFANodes during matching
+ int * groups;
+ /// An array of private data used by NFANodes during matching
+ int * groupIndeces;
+ /// An array of private data used by NFANodes during matching
+ int * groupPos;
+ /// The ending index of the last match
+ int lm;
+ /// The number of capturing groups we have
+ int gc;
+ /// The number of non-capturing groups we havew
+ int ncgc;
+ /// Whether or not we have matched something (used only by findFirstMatch and findNextMatch)
+ int matchedSomething;
+ /// The flags with which we were made
+ unsigned long flags;
+ /// Called by reset to clear the group arrays
+ void clearGroups();
+ public:
+ /// Used internally by match to signify we want the entire string matched
+ const static int MATCH_ENTIRE_STRING;
+ public:
+ /// Cleans up the dynamic memory used by this matcher
+ ~Matcher();
+ /**
+ Replaces the contents of <code>str</code> with the appropriate captured
+ text. <code>str</code> should have at least one back reference, otherwise
+ this function does nothing.
+ @param str The string in which to replace text
+ @return A string with all backreferences appropriately replaced
+ */
+ std::string replaceWithGroups(const std::string & str);
+ /**
+ The flags currently being used by the matcher.
+ @return Zero
+ */
+ unsigned long getFlags() const;
+ /**
+ The text being searched by the matcher.
+ @return the text being searched by the matcher.
+ */
+ std::string getText() const;
+
+ /**
+ Scans the string from start to finish for a match. The entire string must
+ match for this function to return success. Group variables are
+ appropriately set and can be queried after this function returns.
+
+ @return Success if and only if the entire string matches the pattern
+ */
+ bool matches();
+ /**
+ Scans the string for the first substring matching the pattern. The entire
+ string does not necessarily have to match for this function to return
+ success. Group variables are appropriately set and can be queried after
+ this function returns.
+
+ @return Success if any substring matches the specified pattern
+ */
+ bool findFirstMatch();
+ /**
+ Scans the string for the next substring matching the pattern. If no calls
+ have been made to findFirstMatch of findNextMatch since the last call to
+ reset, matches, or setString, then this function's behavior results to
+ that of findFirstMatch.
+
+ @return Success if another substring can be found that matches the pattern
+ */
+ bool findNextMatch();
+ /**
+ Returns a vector of every substring in order which matches the given
+ pattern.
+
+ @return Every substring in order which matches the given pattern
+ */
+ std::vector<std::string> findAll();
+ /**
+ Resets the internal state of the matcher
+ */
+ void reset();
+ /**
+ Same as getText. Left n for backwards compatibilty with old source code
+ @return Returns the string that is currently being used for matching
+ */
+ inline std::string getString() const { return str; }
+ /**
+ Sets the string to scan
+ @param newStr The string to scan for subsequent matches
+ */
+ inline void setString(const std::string & newStr) { str = newStr; reset(); }
+
+ /**
+ Returns the starting index of the specified group.
+ @param groupNum The group to query
+ @return The starting index of the group if it was matched, -1 for an
+ invalid group or if the group was not matched
+ */
+ int getStartingIndex(const int groupNum = 0) const;
+ /**
+ Returns the ending index of the specified group.
+ @param groupNum The group to query
+ @return The ending index of the group if it was matched, -1 for an
+ invalid group or if the group was not matched
+ */
+ int getEndingIndex(const int groupNum = 0) const;
+ /**
+ Returns the specified group. An empty string ("") does not necessarily
+ mean the group was not matched. A group such as (a*b?) could be matched by
+ a zero length. If an empty string is returned, getStartingIndex can be
+ called to determine if the group was actually matched.
+ @param groupNum The group to query
+ @return The text of the group
+ */
+ std::string getGroup(const int groupNum = 0) const;
+ /**
+ Returns every capture group in a vector
+
+ @param includeGroupZero Whether or not include capture group zero
+ @return Every capture group
+ */
+ std::vector<std::string> getGroups(const bool includeGroupZero = 0) const;
+
+ /**
+ Number of captured groups
+ @return number of captured groups.
+ */
+ int getGroupNum() {return gc;}
+
+};
+
+#endif
diff --git a/support/highlight/src/core/re/Pattern.cpp b/support/highlight/src/core/re/Pattern.cpp
new file mode 100644
index 0000000000..b5fde13354
--- /dev/null
+++ b/support/highlight/src/core/re/Pattern.cpp
@@ -0,0 +1,1655 @@
+/**
+ From the author (Jeff Stuart)
+ "
+ Let me start by saying this file is pretty big. If you feel up to it, you can
+ try making changes yourself, but you would be better off to just email me at
+ stuart@cs.ucdavis.edu if you think there is a bug, or have something useful you
+ would like added. This project is very "near and dear" to me, so I am fairly
+ quick to make bug fixes. The header files for Pattern and Matcher are fairly
+ well documented and the function names are pretty self-explanatory, but if you
+ are having any trouble, feel free to email me at stuart@cs.ucdavis.edu.
+
+ If you email me, make sure you put something like C++RE in the subject because
+ I tend to delete email if I don't recognize the name and the subject is
+ something like "I Need Your Help" or "Got A Second" or "I Found It".
+ "
+ */
+
+/*
+ Detailed documentation is provided in this class' header file
+
+ @author Jeffery Stuart
+ @since November 2004
+ @version 1.05.02
+*/
+
+#include "Pattern.h"
+#include "Matcher.h"
+#include <cstring>
+#include <cstdio>
+#include <algorithm>
+#include <cctype>
+
+std::map<std::string, Pattern *> Pattern::compiledPatterns;
+std::map<std::string, std::pair<std::string, unsigned long> > Pattern::registeredPatterns;
+
+const int Pattern::MIN_QMATCH = 0x00000000;
+const int Pattern::MAX_QMATCH = 0x7FFFFFFF;
+
+const unsigned long Pattern::CASE_INSENSITIVE = 0x01;
+const unsigned long Pattern::LITERAL = 0x02;
+const unsigned long Pattern::DOT_MATCHES_ALL = 0x04;
+const unsigned long Pattern::MULTILINE_MATCHING = 0x08;
+const unsigned long Pattern::UNIX_LINE_MODE = 0x10;
+
+#ifdef _WIN32
+ #define str_icmp stricmp
+#else
+ #define str_icmp strcasecmp
+#endif
+
+Pattern::Pattern(const std::string & rhs)
+{
+ matcher = NULL;
+ pattern = rhs;
+ curInd = 0;
+ groupCount = 0;
+ nonCapGroupCount = 0;
+ error = 0;
+ head = NULL;
+}
+// convenience function in case we want to add any extra debugging output
+void Pattern::raiseError()
+{
+ switch (pattern[curInd - 1])
+ {
+ case '*':
+ case ')':
+ case '+':
+ case '?':
+ case ']':
+ case '}':
+ fprintf(stderr, "%s\n%*c^\n", pattern.c_str(), curInd - 1, ' ');
+ fprintf(stderr, "Syntax Error near here. Possible unescaped meta character.\n");
+ break;
+ default:
+ fprintf(stderr, "%s\n%*c^\n", pattern.c_str(), curInd - 1, ' ');
+ fprintf(stderr, "Syntax Error near here. \n");
+ break;
+ }
+ error = 1;
+}
+NFANode * Pattern::registerNode(NFANode * node)
+{
+ nodes[node] = 1;
+ return node;
+}
+
+std::string Pattern::classUnion (std::string s1, std::string s2) const
+{
+ char out[300];
+ std::sort(s1.begin(), s1.end());
+ std::sort(s2.begin(), s2.end());
+ *std::set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), out) = 0;
+ return out;
+}
+std::string Pattern::classIntersect (std::string s1, std::string s2) const
+{
+ char out[300];
+ std::sort(s1.begin(), s1.end());
+ std::sort(s2.begin(), s2.end());
+ *std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), out) = 0;
+ return out;
+}
+std::string Pattern::classNegate (std::string s1) const
+{
+ char out[300];
+ int i, ind = 0;
+ std::map<char, bool> m;
+
+ for (i = 0; i < (int)s1.size(); ++i) m[s1[i]] = 1;
+ for (i = 0xFF; i >= 0; --i) if (m.find((char)i) == m.end()) out[ind++] = (char)i;
+ out[ind] = 0;
+ return std::string(out, ind);
+}
+std::string Pattern::classCreateRange(char low, char hi) const
+{
+ char out[300];
+ int ind = 0;
+ while (low != hi) out[ind++] = low++;
+ out[ind++] = low;
+ return std::string(out, ind);
+}
+
+int Pattern::getInt(int start, int end)
+{
+ int ret = 0;
+ for (; start <= end; ++start) ret = ret * 10 + (pattern[start] - '0');
+ return ret;
+}
+bool Pattern::quantifyCurly(int & sNum, int & eNum)
+{
+ bool good = 1;
+ int i, ci = curInd + 1;
+ int commaInd = ci, endInd = ci, len = pattern.size();
+ sNum = eNum = 0;
+
+ while (endInd < len && pattern[endInd ] != '}') ++endInd;
+ while (commaInd < endInd && pattern[commaInd] != ',') ++commaInd;
+ if (endInd >= len) { raiseError(); return 0; }
+ for (i = ci; good && i < endInd; ++i) if (i != commaInd && !isdigit(pattern[i])) good = 0;
+ if (!good && commaInd < endInd) { raiseError(); return 0; }
+ if (!good) return 0;
+ /* so now everything in here is either a comma (and there is at most one comma) or a digit */
+ if (commaInd == ci) // {,*}
+ {
+ if (endInd == commaInd + 1) { sNum = MIN_QMATCH; eNum = MAX_QMATCH; } // {,} = *
+ else { sNum = MIN_QMATCH; eNum = getInt(commaInd + 1, endInd - 1); } // {,+}
+ }
+ else if (commaInd == endInd - 1) { sNum = getInt(ci, commaInd - 1); eNum = MAX_QMATCH; } // {+,}
+ else if (commaInd == endInd) { sNum = getInt(ci, endInd - 1); eNum = sNum; } // {+}
+ else { sNum = getInt(ci, commaInd - 1); eNum = getInt(commaInd + 1, endInd - 1); } // {+,+}
+ curInd = endInd + 1;
+ return 1;
+}
+NFANode * Pattern::quantifyGroup(NFANode * start, NFANode * stop, const int gn)
+{
+ NFANode * newNode = NULL;
+ int type = 0;
+
+ if (curInd < (int)pattern.size())
+ {
+ char ch = (curInd + 1 >= (int)pattern.size()) ? -1 : pattern[curInd + 1];
+ switch (pattern[curInd])
+ {
+ case '*':
+ ++curInd;
+ switch (ch)
+ {
+ case '?': ++curInd; type = 1; break;
+ case '+': ++curInd; type = 2; break;
+ }
+ newNode = registerNode(new NFAGroupLoopPrologueNode(gn));
+ newNode->next = registerNode(new NFAGroupLoopNode(start, MIN_QMATCH, MAX_QMATCH, gn, type));
+ stop->next = newNode->next;
+ return newNode;
+ case '?':
+ ++curInd;
+ switch (ch)
+ {
+ case '?': ++curInd; type = 1; break;
+ case '+': ++curInd; type = 2; break;
+ }
+ newNode = registerNode(new NFAGroupLoopPrologueNode(gn));
+ newNode->next = registerNode(new NFAGroupLoopNode(start, MIN_QMATCH, 1, gn, type));
+ stop->next = newNode->next;
+ return newNode;
+ case '+':
+ ++curInd;
+ switch (ch)
+ {
+ case '?': ++curInd; type = 1; break;
+ case '+': ++curInd; type = 2; break;
+ }
+ newNode = registerNode(new NFAGroupLoopPrologueNode(gn));
+ newNode->next = registerNode(new NFAGroupLoopNode(start, 1, MAX_QMATCH, gn, type));
+ stop->next = newNode->next;
+ return newNode;
+ case '{':
+ {
+ int s, e;
+ if (quantifyCurly(s, e))
+ {
+ ch = (curInd < (int)pattern.size()) ? pattern[curInd] : -1;
+ switch (ch)
+ {
+ case '?': ++curInd; type = 1; break;
+ case '+': ++curInd; type = 2; break;
+ }
+ newNode = registerNode(new NFAGroupLoopPrologueNode(gn));
+ newNode->next = registerNode(new NFAGroupLoopNode(start, s, e, gn, type));
+ stop->next = newNode->next;
+ return newNode;
+ }
+ }
+ default:
+ break;
+ }
+ }
+ return NULL;
+}
+
+NFANode * Pattern::quantify(NFANode * newNode)
+{
+ if (curInd < (int)pattern.size())
+ {
+ char ch = (curInd + 1 >= (int)pattern.size()) ? -1 : pattern[curInd + 1];
+ switch (pattern[curInd])
+ {
+ case '*':
+ ++curInd;
+ switch (ch)
+ {
+ case '?': ++curInd; newNode = registerNode(new NFALazyQuantifierNode (this, newNode, MIN_QMATCH, MAX_QMATCH)); break;
+ case '+': ++curInd; newNode = registerNode(new NFAPossessiveQuantifierNode(this, newNode, MIN_QMATCH, MAX_QMATCH)); break;
+ default: newNode = registerNode(new NFAGreedyQuantifierNode (this, newNode, MIN_QMATCH, MAX_QMATCH)); break;
+ }
+ break;
+ case '?':
+ ++curInd;
+ switch (ch)
+ {
+ case '?': ++curInd; newNode = registerNode(new NFALazyQuantifierNode (this, newNode, MIN_QMATCH, 1)); break;
+ case '+': ++curInd; newNode = registerNode(new NFAPossessiveQuantifierNode(this, newNode, MIN_QMATCH, 1)); break;
+ default: newNode = registerNode(new NFAGreedyQuantifierNode (this, newNode, MIN_QMATCH, 1)); break;
+ }
+ break;
+ case '+':
+ ++curInd;
+ switch (ch)
+ {
+ case '?': ++curInd; newNode = registerNode(new NFALazyQuantifierNode (this, newNode, 1, MAX_QMATCH)); break;
+ case '+': ++curInd; newNode = registerNode(new NFAPossessiveQuantifierNode(this, newNode, 1, MAX_QMATCH)); break;
+ default: newNode = registerNode(new NFAGreedyQuantifierNode (this, newNode, 1, MAX_QMATCH)); break;
+ }
+ break;
+ case '{':
+ {
+ int s, e;
+ if (quantifyCurly(s, e))
+ {
+ ch = (curInd < (int)pattern.size()) ? pattern[curInd] : -1;
+ switch (ch)
+ {
+ case '?': ++curInd; newNode = registerNode(new NFALazyQuantifierNode (this, newNode, s, e)); break;
+ case '+': ++curInd; newNode = registerNode(new NFAPossessiveQuantifierNode(this, newNode, s, e)); break;
+ default: newNode = registerNode(new NFAGreedyQuantifierNode (this, newNode, s, e)); break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return newNode;
+}
+std::string Pattern::parseClass()
+{
+ std::string t, ret = "";
+ char ch, c1, c2;
+ bool inv = 0, neg = 0, quo = 0;
+
+ if (curInd < (int)pattern.size() && pattern[curInd] == '^')
+ {
+ ++curInd;
+ neg = 1;
+ }
+ while (curInd < (int)pattern.size() && pattern[curInd] != ']')
+ {
+ ch = pattern[curInd++];
+ if (ch == '[')
+ {
+ t = parseClass();
+ ret = classUnion(ret, t);
+ }
+ /*else if (ch == '-')
+ {
+ raiseError();
+ curInd = pattern.size();
+ }*/
+ else if (ch == '&' && curInd < (int)pattern.size() && pattern[curInd] == '&')
+ {
+ if (pattern[++curInd] != '[')
+ {
+ raiseError();
+ curInd = pattern.size();
+ }
+ else
+ {
+ ++curInd;
+ t = parseClass();
+ ret = classIntersect(ret, t);
+ }
+ }
+ else if (ch == '\\')
+ {
+ t = parseEscape(inv, quo);
+ if (quo)
+ {
+ raiseError();
+ curInd = pattern.size();
+ }
+ else if (inv || t.size() > 1) // cant be part of a range (a-z)
+ {
+ if (inv) t = classNegate(t);
+ ret = classUnion(ret, t);
+ }
+ else if (curInd < (int)pattern.size() && pattern[curInd] == '-') // part of a range (a-z)
+ {
+ c1 = t[0];
+ ++curInd;
+ if (curInd >= (int)pattern.size()) raiseError();
+ else
+ {
+ c2 = pattern[curInd++];
+ if (c2 == '\\')
+ {
+ t = parseEscape(inv, quo);
+ if (quo)
+ {
+ raiseError();
+ curInd = pattern.size();
+ }
+ else if (inv || t.size() > 1) raiseError();
+ else ret = classUnion(ret, classCreateRange(c1, c2));
+ }
+ else if (c2 == '[' || c2 == ']' || c2 == '-' || c2 == '&')
+ {
+ raiseError();
+ curInd = pattern.size();
+ }
+ else ret = classUnion(ret, classCreateRange(c1, c2));
+ }
+ }
+ else
+ {
+ ret = classUnion(ret, t);
+ }
+ }
+ else if (curInd < (int)pattern.size() && pattern[curInd] == '-')
+ {
+ c1 = ch;
+ ++curInd;
+ if (curInd >= (int)pattern.size()) raiseError();
+ else
+ {
+ c2 = pattern[curInd++];
+ if (c2 == '\\')
+ {
+ t = parseEscape(inv, quo);
+ if (quo)
+ {
+ raiseError();
+ curInd = pattern.size();
+ }
+ else if (inv || t.size() > 1) raiseError();
+ else ret = classUnion(ret, classCreateRange(c1, c2));
+ }
+ else if (c2 == '[' || c2 == ']' || c2 == '-' || c2 == '&')
+ {
+ raiseError();
+ curInd = pattern.size();
+ }
+ else
+ {
+ ret = classUnion(ret, classCreateRange(c1, c2));
+ }
+ }
+ }
+ else
+ {
+ ret += " ";
+ ret[ret.size() - 1] = ch;
+ }
+ }
+ if (curInd >= (int)pattern.size() || pattern[curInd] != ']')
+ {
+ raiseError();
+ ret = "";
+ }
+ else
+ {
+ ++curInd;
+ if (neg) ret = classNegate(ret);
+ }
+ return ret;
+}
+std::string Pattern::parsePosix()
+{
+ std::string s7 = pattern.substr(curInd, 7);
+ if (s7 == "{Lower}") { curInd += 7; return "abcdefghijklmnopqrstuvwxyz"; }
+ if (s7 == "{Upper}") { curInd += 7; return "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
+ if (s7 == "{Alpha}") { curInd += 7; return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
+ if (s7 == "{Digit}") { curInd += 7; return "0123456789"; }
+ if (s7 == "{Alnum}") { curInd += 7; return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; }
+ if (s7 == "{Punct}") { curInd += 7; return "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; }
+ if (s7 == "{Graph}") { curInd += 7; return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; }
+ if (s7 == "{Print}") { curInd += 7; return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; }
+ if (s7 == "{Blank}") { curInd += 7; return " \t"; }
+ if (s7 == "{Space}") { curInd += 7; return " \t\n\x0B\f\r"; }
+ if (s7 == "{Cntrl}")
+ {
+ int i;
+ std::string s = " ";
+
+ for (i = 0; i < 5; ++i) s += s;
+ s += " ";
+ for (i = 0; i <= 0x1F; ++i) s[i] = i;
+ s[0x20] = 0x7F;
+ curInd += 7;
+ return s;
+ }
+ if (s7 == "{ASCII}")
+ {
+ std::string s(0x80, ' ');
+ for (int i = 0; i < 0x80; ++i) s[i] = i;
+ curInd += 7;
+ return s;
+ }
+ if (pattern.substr(curInd, 8) == "{XDigit}") { curInd += 8; return "abcdefABCDEF0123456789"; }
+ raiseError();
+ return "";
+}
+NFANode * Pattern::parseBackref()
+{
+ #define is_dig(x) ((x) >= '0' && (x) <= '9')
+ #define to_int(x) ((x) - '0')
+ int ci = curInd;
+ int oldRef = 0, ref = 0;
+
+ while (ci < (int)pattern.size() && is_dig(pattern[ci]) && (ref < 10 || ref < groupCount))
+ {
+ oldRef = ref;
+ ref = ref * 10 + to_int(pattern[ci++]);
+ }
+ if (ci == (int)pattern.size())
+ {
+ oldRef = ref;
+ ++ci;
+ }
+ if (oldRef < 0 || ci <= curInd)
+ {
+ raiseError();
+ return registerNode(new NFAReferenceNode(-1));
+ }
+ curInd = ci;
+ return registerNode(new NFAReferenceNode(ref));
+
+ #undef is_dig
+ #undef to_int
+}
+std::string Pattern::parseOctal()
+{
+ #define islowoc(x) ((x) >= '0' && (x) <= '3')
+ #define isoc(x) ((x) >= '0' && (x) <= '7')
+ #define fromoc(x) ((x) - '0')
+ int ci = curInd;
+ char ch1 = (ci + 0 < (int)pattern.size()) ? pattern[ci + 0] : -1;
+ char ch2 = (ci + 1 < (int)pattern.size()) ? pattern[ci + 1] : -1;
+ char ch3 = (ci + 2 < (int)pattern.size()) ? pattern[ci + 2] : -1;
+ std::string s = " ";
+
+ if (islowoc(ch1) && isoc(ch2))
+ {
+ curInd += 2;
+ s[0] = fromoc(ch1) * 8 + fromoc(ch2);
+ if (isoc(ch3))
+ {
+ ++curInd;
+ s[0] = s[0] * 8 + fromoc(ch3);
+ }
+ }
+ else if (isoc(ch1) && isoc(ch2))
+ {
+ curInd += 2;
+ s[0] = fromoc(ch1) * 8 + fromoc(ch2);
+ }
+ else raiseError();
+
+ return s;
+ #undef islowoc
+ #undef isoc
+ #undef fromoc
+}
+std::string Pattern::parseHex()
+{
+ #define to_low(x) (((x) >= 'A' && (x) <= 'Z') ? ((x) - 'A' + 'a') : (x))
+ #define is_dig(x) ((x) >= '0' && (x) <= '9')
+ #define is_hex(x) (is_dig(x) || (to_low(x) >= 'a' && to_low(x) <= 'f'))
+ #define to_int(x) ((is_dig(x)) ? ((x) - '0') : (to_low(x) - 'a' + 10))
+
+ int ci = curInd;
+ char ch1 = (ci + 0 < (int)pattern.size()) ? pattern[ci + 0] : -1;
+ char ch2 = (ci + 1 < (int)pattern.size()) ? pattern[ci + 1] : -1;
+ std::string s = " ";
+
+ if (is_hex(ch1) && is_hex(ch2))
+ {
+ curInd += 2;
+ s[0] = (to_int(ch1) << 4 & 0xF0) | (to_int(ch2) & 0x0F);
+ }
+
+ return s;
+ #undef to_low
+ #undef is_dig
+ #undef is_hex
+ #undef to_int
+}
+std::string Pattern::parseEscape(bool & inv, bool & quo)
+{
+ char ch = pattern[curInd++];
+ std::string classes = "";
+
+ if (curInd > (int)pattern.size())
+ {
+ raiseError();
+ return NULL;
+ }
+
+ quo = 0;
+ inv = 0;
+ switch (ch)
+ {
+ case 'p': classes = parsePosix(); break;
+ case 'P': classes = "!!"; classes += parsePosix(); break;
+ case 'd': classes = "0123456789"; break;
+ case 'D': classes = "!!0123456789"; break;
+ case 's': classes = " \t\r\n\f"; break;
+ case 'S': classes = "!! \t\r\n\f"; break;
+ case 'w': classes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; break;
+ case 'W': classes = "!!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; break;
+ case '0': classes = parseOctal(); break;
+ case 'x': classes = parseHex(); break;
+
+ case 'Q': quo = 1; break;
+ case 't': classes = "\t"; break;
+ case 'r': classes = "\r"; break;
+ case 'n': classes = "\n"; break;
+ case 'f': classes = "\f"; break;
+ case 'a': classes = "\a"; break;
+ case 'e': classes = "\r"; break;
+ default: classes = " "; classes[0] = ch; break;
+ }
+ if (classes.substr(0, 2) == "!!")
+ {
+ classes = classes.substr(2);
+ inv = 1;
+ }
+ return classes;
+}
+NFANode * Pattern::parseRegisteredPattern(NFANode ** end)
+{
+ int i, j;
+ std::string s;
+ NFANode * ret = NULL;
+ for (i = curInd; i < (int)pattern.size() && pattern[i] != '}'; ++i) { }
+ if (pattern[i] != '}') { raiseError(); return NULL; }
+ if (i == curInd + 1) { raiseError(); return NULL; } // {}
+ if (
+ !(
+ (pattern[curInd] >= 'a' && pattern[curInd] <= 'z') ||
+ (pattern[curInd] >= 'A' && pattern[curInd] <= 'Z') ||
+ (pattern[curInd] == '_')
+ )
+ )
+ {
+ raiseError();
+ return NULL;
+ }
+ for (j = curInd; !error && j < i; ++j)
+ {
+ if (
+ !(
+ (pattern[j] >= 'a' && pattern[j] <= 'z') ||
+ (pattern[j] >= 'A' && pattern[j] <= 'Z') ||
+ (pattern[j] >= '0' && pattern[j] <= '9') ||
+ (pattern[j] == '_')
+ )
+ )
+ {
+ raiseError();
+ return NULL;
+ }
+ }
+ s = pattern.substr(curInd, i - curInd);
+ if (registeredPatterns.find(s) == registeredPatterns.end()) raiseError();
+ else
+ {
+ unsigned long oflags = flags;
+ std::string op = pattern;
+ int ci = i + 1;
+
+ pattern = registeredPatterns[s].first;
+ curInd = 0;
+ flags = registeredPatterns[s].second;
+
+ --groupCount;
+ ret = parse(0, 0, end);
+
+ pattern = op;
+ curInd = ci;
+ flags = oflags;
+ }
+ if (error) { *end = ret = NULL; }
+ return ret;
+}
+
+// look behind should interpret everything as a literal (except \\) since the
+// pattern must have a concrete length
+NFANode * Pattern::parseBehind(const bool pos, NFANode ** end)
+{
+ std::string t = "";
+ while (curInd < (int)pattern.size() && pattern[curInd] != ')')
+ {
+ char ch = pattern[curInd++];
+ t += " ";
+ if (ch == '\\')
+ {
+ if (curInd + 1 >= (int)pattern.size())
+ {
+ raiseError();
+ return *end = registerNode(new NFACharNode(' '));
+ }
+ ch = pattern[curInd++];
+ }
+ t[t.size() - 1] = ch;
+ }
+ if (curInd >= (int)pattern.size() || pattern[curInd] != ')') raiseError();
+ else ++curInd;
+ return *end = registerNode(new NFALookBehindNode(t, pos));
+}
+NFANode * Pattern::parseQuote()
+{
+ bool done = 0;
+ std::string s = "";
+
+ while (!done)
+ {
+ if (curInd >= (int)pattern.size())
+ {
+ raiseError();
+ done = 1;
+ }
+ else if (pattern.substr(curInd, 2) == "\\E")
+ {
+ curInd += 2;
+ done = 1;
+ }
+ else if (pattern[curInd] == '\\')
+ {
+ s += " ";
+ s[s.size() - 1] = pattern[++curInd];
+ ++curInd;
+ }
+ else
+ {
+ s += " ";
+ s[s.size() - 1] = pattern[curInd++];
+ }
+ }
+ if ((flags & Pattern::CASE_INSENSITIVE) != 0) return registerNode(new NFACIQuoteNode(s));
+ return registerNode(new NFAQuoteNode(s));
+}
+NFANode * Pattern::parse(const bool inParen, const bool inOr, NFANode ** end)
+{
+ NFANode * start, * cur, * next = NULL;
+ std::string t;
+ int grc = groupCount++;
+ bool inv, quo;
+ bool ahead = 0, pos = 0, noncap = 0, indep = 0;
+
+ if (inParen)
+ {
+ if (pattern[curInd] == '?')
+ {
+ ++curInd;
+ --groupCount;
+ if (pattern[curInd] == ':') { noncap = 1; ++curInd; grc = --nonCapGroupCount; }
+ else if (pattern[curInd] == '=') { ++curInd; ahead = 1; pos = 1; }
+ else if (pattern[curInd] == '!') { ++curInd; ahead = 1; pos = 0; }
+ else if (pattern.substr(curInd, 2) == "<=") { curInd += 2; return parseBehind(1, end); }
+ else if (pattern.substr(curInd, 2) == "<!") { curInd += 2; return parseBehind(0, end); }
+ else if (pattern[curInd] == '>') { ++curInd; indep = 1; }
+ else { raiseError(); return NULL; }
+ if (noncap) cur = start = registerNode(new NFAGroupHeadNode(grc));
+ else cur = start = registerNode(new NFASubStartNode);
+ }
+ else cur = start = registerNode(new NFAGroupHeadNode(grc));
+ }
+ else cur = start = registerNode(new NFASubStartNode);
+ while (curInd < (int)pattern.size())
+ {
+ char ch = pattern[curInd++];
+
+ next = NULL;
+ if (error) return NULL;
+ switch (ch)
+ {
+ case '^':
+ if ((flags & Pattern::MULTILINE_MATCHING) != 0) next = registerNode(new NFAStartOfLineNode);
+ else next = registerNode(new NFAStartOfInputNode);
+ break;
+ case '$':
+ if ((flags & Pattern::MULTILINE_MATCHING) != 0) next = registerNode(new NFAEndOfLineNode);
+ else next = registerNode(new NFAEndOfInputNode(0));
+ break;
+ case '|':
+ --groupCount;
+ cur->next = registerNode(new NFAAcceptNode);
+ cur = start = registerNode(new NFAOrNode(start, parse(inParen, 1)));
+ break;
+ case '\\':
+ if (curInd < (int)pattern.size())
+ {
+ bool eoi = 0;
+ switch (pattern[curInd])
+ {
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': next = parseBackref(); break;
+ case 'A': ++curInd; next = registerNode(new NFAStartOfInputNode); break;
+ case 'B': ++curInd; next = registerNode(new NFAWordBoundaryNode(0)); break;
+ case 'b': ++curInd; next = registerNode(new NFAWordBoundaryNode(1)); break;
+ case 'G': ++curInd; next = registerNode(new NFAEndOfMatchNode); break;
+ case 'Z': eoi = 1;
+ case 'z': ++curInd; next = registerNode(new NFAEndOfInputNode(eoi)); break;
+ default:
+ t = parseEscape(inv, quo);
+ if (!quo)
+ {
+ if (t.size() > 1 || inv)
+ {
+ if ((flags & Pattern::CASE_INSENSITIVE) != 0) next = registerNode(new NFACIClassNode(t, inv));
+ else next = registerNode(new NFAClassNode(t, inv));
+ }
+ else
+ {
+ next = registerNode(new NFACharNode(t[0]));
+ }
+ }
+ else
+ {
+ next = parseQuote();
+ }
+ }
+ }
+ else raiseError();
+ break;
+ case '[':
+ if ((flags & Pattern::CASE_INSENSITIVE) == 0)
+ {
+ NFAClassNode * clazz = new NFAClassNode();
+ std::string s = parseClass();
+ for (int i = 0; i < (int)s.size(); ++i) clazz->vals[s[i]] = 1;
+ next = registerNode(clazz);
+ }
+ else
+ {
+ NFACIClassNode * clazz = new NFACIClassNode();
+ std::string s = parseClass();
+ for (int i = 0; i < (int)s.size(); ++i) clazz->vals[tolower(s[i])] = 1;
+ next = registerNode(clazz);
+ }
+ break;
+ case '.':
+ {
+ bool useN = 1, useR = 1;
+ NFAClassNode * clazz = new NFAClassNode(1);
+ if ((flags & Pattern::UNIX_LINE_MODE) != 0) useR = 0;
+ if ((flags & Pattern::DOT_MATCHES_ALL) != 0) useN = useR = 0;
+ if (useN) clazz->vals['\n'] = 1;
+ if (useR) clazz->vals['\r'] = 1;
+ next = registerNode(clazz);
+ }
+ break;
+ case '(':
+ {
+ NFANode * end, * t1, * t2;
+ t1 = parse(1, 0, &end);
+ if (!t1) raiseError();
+ else if (t1->isGroupHeadNode() && (t2 = quantifyGroup(t1, end, grc)) != NULL)
+ {
+ cur->next = t2;
+ cur = t2->next;
+ }
+ else
+ {
+ cur->next = t1;
+ cur = end;
+ }
+ }
+ break;
+ case ')':
+ if (!inParen) raiseError();
+ else if (inOr)
+ {
+ --curInd;
+ cur = cur->next = registerNode(new NFAAcceptNode);
+ return start;
+ }
+ else
+ {
+ if (ahead)
+ {
+ cur = cur->next = registerNode(new NFAAcceptNode);
+ return *end = registerNode(new NFALookAheadNode(start, pos));
+ }
+ else if (indep)
+ {
+ cur = cur->next = registerNode(new NFAAcceptNode);
+ return *end = registerNode(new NFAPossessiveQuantifierNode(this, start, 1, 1));
+ }
+ else // capping or noncapping, it doesnt matter
+ {
+ *end = cur = cur->next = registerNode(new NFAGroupTailNode(grc));
+ next = quantifyGroup(start, *end, grc);
+ if (next)
+ {
+ start = next;
+ *end = next->next;
+ }
+ return start;
+ }
+ }
+ break;
+ case '{': // registered pattern
+ cur->next = parseRegisteredPattern(&next);
+ if (cur->next) cur = next;
+ break;
+ case '*':
+ case '+':
+ case '?':
+ case '}':
+ case ']':
+ raiseError();
+ break;
+ default:
+ if ((flags & Pattern::CASE_INSENSITIVE) != 0) next = registerNode(new NFACICharNode(ch));
+ else next = registerNode(new NFACharNode(ch));
+ break;
+ }
+ if (next)
+ {
+ cur = cur->next = quantify(next);
+ }
+ }
+ if (inParen) raiseError();
+ else
+ {
+ if (inOr) cur = cur->next = registerNode(new NFAAcceptNode);
+ if (end) *end = cur;
+ }
+
+ if (error) return NULL;
+
+ return start;
+}
+
+Pattern * Pattern::compile(const std::string & pattern, const unsigned long mode)
+{
+ Pattern * p = new Pattern(pattern);
+ NFANode * end;
+
+ p->flags = mode;
+ if ((mode & Pattern::LITERAL) != 0)
+ {
+ p->head = p->registerNode(new NFAStartNode);
+ if ((mode & Pattern::CASE_INSENSITIVE) != 0) p->head->next = p->registerNode(new NFACIQuoteNode(pattern));
+ else p->head->next = p->registerNode(new NFAQuoteNode(pattern));
+ p->head->next->next = p->registerNode(new NFAEndNode);
+ }
+ else
+ {
+ p->head = p->parse(0, 0, &end);
+ if (!p->head)
+ {
+ delete p;
+ p = NULL;
+ }
+ else
+ {
+ if (!(p->head && p->head->isStartOfInputNode()))
+ {
+ NFANode * n = p->registerNode(new NFAStartNode);
+ n->next = p->head;
+ p->head = n;
+ }
+ end->next = p->registerNode(new NFAEndNode);
+ }
+ }
+ if (p != NULL)
+ {
+ p->matcher = new Matcher(p, "");
+ }
+
+ return p;
+}
+
+Pattern * Pattern::compileAndKeep(const std::string & pattern, const unsigned long mode)
+{
+ Pattern * ret = NULL;
+ std::map<std::string, Pattern*>::iterator it = compiledPatterns.find(pattern);
+
+ if (it != compiledPatterns.end())
+ {
+ ret = it->second;
+ }
+ else
+ {
+ ret = compile(pattern, mode);
+ compiledPatterns[pattern] = ret;
+ }
+
+ return ret;
+}
+std::string Pattern::replace(const std::string & pattern, const std::string & str,
+ const std::string & replacementText, const unsigned long mode)
+{
+ std::string ret;
+ Pattern * p = Pattern::compile(pattern, mode);
+ if (p)
+ {
+ ret = p->replace(str, replacementText);
+ delete p;
+ }
+ return ret;
+}
+
+std::vector<std::string> Pattern::split(const std::string & pattern, const std::string & str, const bool keepEmptys,
+ const unsigned long limit, const unsigned long mode)
+{
+ std::vector<std::string> ret;
+ Pattern * p = Pattern::compile(pattern, mode);
+ if (p)
+ {
+ ret = p->split(str, keepEmptys, limit);
+ delete p;
+ }
+ return ret;
+}
+
+std::vector<std::string> Pattern::findAll(const std::string & pattern, const std::string & str, const unsigned long mode)
+{
+ std::vector<std::string> ret;
+ Pattern * p = Pattern::compile(pattern, mode);
+ if (p)
+ {
+ ret = p->findAll(str);
+ delete p;
+ }
+ return ret;
+}
+
+bool Pattern::matches(const std::string & pattern, const std::string & str, const unsigned long mode)
+{
+ bool ret = 0;
+ Pattern * p = compile(pattern, mode);
+
+ if (p)
+ {
+ ret = p->matches(str);
+ delete p;
+ }
+
+ return ret;
+}
+
+bool Pattern::registerPattern(const std::string & name, const std::string & pattern, const unsigned long mode)
+{
+ Pattern * p = Pattern::compile(pattern, mode);
+ if (!p) return 0;
+ Pattern::registeredPatterns[name] = std::make_pair(pattern, mode);
+ delete p;
+ return 1;
+}
+
+void Pattern::unregisterPatterns()
+{
+ registeredPatterns.clear();
+}
+void Pattern::clearPatternCache()
+{
+ std::map<std::string, Pattern*>::iterator it;
+ for (it = compiledPatterns.begin(); it != compiledPatterns.end(); ++it)
+ {
+ delete it->second;
+ }
+ compiledPatterns.clear();
+}
+
+std::pair<std::string, int> Pattern::findNthMatch(const std::string & pattern, const std::string & str,
+ const int matchNum, const unsigned long mode)
+{
+ std::pair<std::string, int> ret;
+ Pattern * p = Pattern::compile(pattern, mode);
+
+ ret.second = -1;
+ if (p)
+ {
+ int i = -1;
+ p->matcher->setString(str);
+ while (i < matchNum && p->matcher->findNextMatch()) { ++i; }
+ if (i == matchNum && p->matcher->getStartingIndex() >= 0)
+ {
+ ret.first = p->matcher->getGroup(0);
+ ret.second = p->matcher->getStartingIndex();
+ }
+ delete p;
+ }
+
+ return ret;
+}
+
+Pattern::~Pattern()
+{
+ /*
+ nodes.clear();
+ if (head) head->findAllNodes(nodes);
+ */
+ if (matcher) delete matcher;
+ for (std::map<NFANode*, bool>::iterator it = nodes.begin(); it != nodes.end(); ++it)
+ {
+ delete it->first;
+ }
+}
+std::string Pattern::replace(const std::string & str, const std::string & replacementText)
+{
+ int li = 0;
+ std::string ret = "";
+
+ matcher->setString(str);
+ while (matcher->findNextMatch())
+ {
+ ret += str.substr(li, matcher->getStartingIndex() - li);
+ ret += matcher->replaceWithGroups(replacementText);
+ li = matcher->getEndingIndex();
+ }
+ ret += str.substr(li);
+
+ return ret;
+}
+std::vector<std::string> Pattern::split(const std::string & str, const bool keepEmptys, const unsigned long limit)
+{
+ unsigned long lim = (limit == 0 ? MAX_QMATCH : limit);
+ int li = 0;
+ std::vector<std::string> ret;
+
+ matcher->setString(str);
+
+ while (matcher->findNextMatch() && ret.size() < lim)
+ {
+ if (matcher->getStartingIndex() == 0 && keepEmptys) ret.push_back("");
+ if ((matcher->getStartingIndex() != matcher->getEndingIndex()) || keepEmptys)
+ {
+ ret.push_back(str.substr(li, matcher->getStartingIndex() - li));
+ li = matcher->getEndingIndex();
+ }
+ }
+ if (li != (int)str.size()) ret.push_back(str.substr(li));
+
+ return ret;
+}
+std::vector<std::string> Pattern::findAll(const std::string & str)
+{
+ matcher->setString(str);
+ return matcher->findAll();
+}
+bool Pattern::matches(const std::string & str)
+{
+ matcher->setString(str);
+ return matcher->matches();
+}
+unsigned long Pattern::getFlags() const
+{
+ return flags;
+}
+std::string Pattern::getPattern() const
+{
+ return pattern;
+}
+Matcher * Pattern::createMatcher(const std::string & str)
+{
+ return new Matcher(this, str);
+}
+
+// NFANode
+
+NFANode::NFANode() { next = NULL; }
+NFANode::~NFANode() { }
+void NFANode::findAllNodes(std::map<NFANode*, bool> & soFar)
+{
+ if (soFar.find(this) == soFar.end()) return;
+ soFar[this] = 1;
+ if (next) next->findAllNodes(soFar);
+}
+
+// NFACharNode
+
+NFACharNode::NFACharNode(const char c) { ch = c; }
+int NFACharNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (curInd < (int)str.size() && str[curInd] == ch) return next->match(str, matcher, curInd + 1);
+ return -1;
+}
+
+// NFACICharNode
+
+NFACICharNode::NFACICharNode(const char c) { ch = tolower(c); }
+int NFACICharNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (curInd < (int)str.size() && tolower(str[curInd]) == ch) return next->match(str, matcher, curInd + 1);
+ return -1;
+}
+
+// NFAStartNode
+
+NFAStartNode::NFAStartNode() { }
+int NFAStartNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int ret = -1, ci = curInd;
+
+ matcher->starts[0] = curInd;
+ if ((matcher->getFlags() & Matcher::MATCH_ENTIRE_STRING) == (unsigned int)Matcher::MATCH_ENTIRE_STRING)
+ {
+ if (curInd != 0)
+ {
+ matcher->starts[0] = -1;
+ return -1;
+ }
+ return next->match(str, matcher, 0);
+ }
+ while ((ret = next->match(str, matcher, ci)) == -1 && ci < (int)str.size())
+ {
+ matcher->clearGroups();
+ matcher->starts[0] = ++ci;
+ }
+ if (ret < 0) matcher->starts[0] = -1;
+ return ret;
+}
+
+// NFAEndNode
+
+NFAEndNode::NFAEndNode() { }
+int NFAEndNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ matcher->ends[0] = curInd;
+ if ((matcher->getFlags() & Matcher::MATCH_ENTIRE_STRING) != 0)
+ {
+ if (curInd == (int)str.size()) return curInd;
+ matcher->ends[0] = -1;
+ return -1;
+ }
+ return curInd;
+}
+
+// NFAQuantifierNode
+
+void NFAQuantifierNode::findAllNodes(std::map<NFANode*, bool> & soFar)
+{
+ inner->findAllNodes(soFar);
+ NFANode::findAllNodes(soFar);
+}
+NFAQuantifierNode::NFAQuantifierNode(Pattern * pat, NFANode * internal, const int minMatch, const int maxMatch)
+{
+ inner = internal;
+ inner->next = pat->registerNode(new NFAAcceptNode);
+ min = (minMatch < Pattern::MIN_QMATCH) ? Pattern::MIN_QMATCH : minMatch;
+ max = (maxMatch > Pattern::MAX_QMATCH) ? Pattern::MAX_QMATCH : maxMatch;
+}
+
+int NFAQuantifierNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int i0, i1, i2 = 0;
+
+ i0 = i1 = curInd;
+ while (i2 < min)
+ {
+
+ ++i2;
+ i1 = inner->match(str, matcher, i0);
+ if (i1 <= i0) return i1; // i1 < i0 means i1 is -1
+ i0 = i1;
+ }
+
+ return i1;
+}
+// NFAGreedyQuantifierNode
+
+NFAGreedyQuantifierNode::NFAGreedyQuantifierNode(Pattern * pat, NFANode * internal, const int minMatch, const int maxMatch)
+ : NFAQuantifierNode(pat, internal, minMatch, maxMatch) { }
+int NFAGreedyQuantifierNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int t = NFAQuantifierNode::match(str, matcher, curInd);
+ if (t != -1) return matchInternal(str, matcher, t, min);
+ return t;
+}
+int NFAGreedyQuantifierNode::matchInternal(const std::string & str, Matcher * matcher, const int curInd, const int soFar) const
+{
+ if (soFar >= max) return next->match(str, matcher, curInd);
+
+ int i, j;
+
+ i = inner->match(str, matcher, curInd);
+ if (i != -1)
+ {
+ j = matchInternal(str, matcher, i, soFar + 1);
+ if (j != -1) return j;
+ }
+ return next->match(str, matcher, curInd);
+}
+
+// NFALazyQuantifierNode
+
+NFALazyQuantifierNode::NFALazyQuantifierNode(Pattern * pat, NFANode * internal, const int minMatch, const int maxMatch)
+ : NFAQuantifierNode(pat, internal, minMatch, maxMatch) { }
+int NFALazyQuantifierNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int i, j, m = NFAQuantifierNode::match(str, matcher, curInd);
+
+ if (m == -1) return -1;
+
+ for (i = min; i < max; ++i)
+ {
+ j = next->match(str, matcher, m);
+ if (j == -1)
+ {
+ j = inner->match(str, matcher, m);
+ // if j < m, then j is -1, so we bail.
+ // if j == m, then we would just go and call next->match on the same index,
+ // but it already failed trying to match right there, so we know we can
+ // just bail
+ if (j <= m) return -1;
+ m = j;
+ }
+ else return j;
+ }
+ return next->match(str, matcher, m);
+}
+
+// NFAPossessiveQuantifierNode
+
+NFAPossessiveQuantifierNode::NFAPossessiveQuantifierNode(Pattern * pat, NFANode * internal, const int minMatch, const int maxMatch)
+ : NFAQuantifierNode(pat, internal, minMatch, maxMatch) { }
+int NFAPossessiveQuantifierNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int i, j, m = NFAQuantifierNode::match(str, matcher, curInd);
+
+ if (m == -1) return -1;
+ for (i = min; i < max; ++i)
+ {
+ j = inner->match(str, matcher, m);
+ if (j <= m) return next->match(str, matcher, m);
+ m = j;
+ }
+ return next->match(str, matcher, m);
+}
+
+// NFAAcceptNode
+
+NFAAcceptNode::NFAAcceptNode() { }
+int NFAAcceptNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (!next) return curInd;
+ else return next->match(str, matcher, curInd);
+}
+
+// NFAClassNode
+
+NFAClassNode::NFAClassNode(const bool invert)
+{
+ inv = invert;
+}
+NFAClassNode::NFAClassNode(const std::string & clazz, const bool invert)
+{
+ inv = invert;
+ for (int i = 0; i < (int)clazz.size(); ++i) vals[clazz[i]] = 1;
+}
+int NFAClassNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (curInd < (int)str.size() && ((vals.find(str[curInd]) != vals.end()) ^ inv))
+ {
+ return next->match(str, matcher, curInd + 1);
+ }
+ return -1;
+}
+
+// NFACIClassNode
+
+NFACIClassNode::NFACIClassNode(const bool invert)
+{
+ inv = invert;
+}
+NFACIClassNode::NFACIClassNode(const std::string & clazz, const bool invert)
+{
+ inv = invert;
+ for (int i = 0; i < (int)clazz.size(); ++i) vals[tolower(clazz[i])] = 1;
+}
+int NFACIClassNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (curInd < (int)str.size() && ((vals.find(tolower(str[curInd])) != vals.end()) ^ inv))
+ {
+ return next->match(str, matcher, curInd + 1);
+ }
+ return -1;
+}
+
+#undef to_lower
+
+// NFASubStartNode
+
+NFASubStartNode::NFASubStartNode() { }
+int NFASubStartNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ return next->match(str, matcher, curInd);
+}
+
+// NFAOrNode
+
+NFAOrNode::NFAOrNode(NFANode * first, NFANode * second) : one(first), two(second) { }
+void NFAOrNode::findAllNodes(std::map<NFANode*, bool> & soFar)
+{
+ if (one) one->findAllNodes(soFar);
+ if (two) two->findAllNodes(soFar);
+ NFANode::findAllNodes(soFar);
+}
+int NFAOrNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int ci = one->match(str, matcher, curInd);
+
+ if (ci != -1) ci = next->match(str, matcher, ci);
+ if (ci != -1) return ci;
+ if (ci == -1) ci = two->match(str, matcher, curInd);
+ if (ci != -1) ci = next->match(str, matcher, ci);
+ return ci;
+}
+
+// NFAQuoteNode
+
+NFAQuoteNode::NFAQuoteNode(const std::string & quoted) : qStr(quoted) { }
+int NFAQuoteNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (curInd + qStr.size() > str.size()) return -1;
+ if (str.substr(curInd, qStr.size()) != qStr) return -1;
+ return next->match(str, matcher, curInd + qStr.size());
+}
+
+// NFACIQuoteNode
+
+NFACIQuoteNode::NFACIQuoteNode(const std::string & quoted) : qStr(quoted) { }
+int NFACIQuoteNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (curInd + qStr.size() > str.size()) return -1;
+ if (str_icmp(str.substr(curInd, qStr.size()).c_str(), qStr.c_str())) return -1;
+ return next->match(str, matcher, qStr.size());
+}
+
+// NFALookAheadNode
+
+NFALookAheadNode::NFALookAheadNode(NFANode * internal, const bool positive) : NFANode(), pos(positive), inner(internal) { }
+void NFALookAheadNode::findAllNodes(std::map<NFANode*, bool> & soFar)
+{
+ if (inner) inner->findAllNodes(soFar);
+ NFANode::findAllNodes(soFar);
+}
+int NFALookAheadNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ return ((inner->match(str, matcher, curInd) == -1) ^ pos) ? next->match(str, matcher, curInd) : -1;
+}
+
+// NFALookBehindNode
+
+NFALookBehindNode::NFALookBehindNode(const std::string & str, const bool positive) : pos(positive), mStr(str) { }
+int NFALookBehindNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (pos)
+ {
+ if (curInd < (int)mStr.size()) return -1;
+ if (str.substr(curInd - mStr.size(), mStr.size()) == mStr) return next->match(str, matcher, curInd);
+ }
+ else
+ {
+ if (curInd < (int)mStr.size()) return next->match(str, matcher, curInd);
+ if (str.substr(curInd - mStr.size(), mStr.size()) == mStr) return -1;
+ return next->match(str, matcher, curInd);
+ }
+ return -1;
+}
+
+// NFAStartOfLineNode
+
+NFAStartOfLineNode::NFAStartOfLineNode() { }
+int NFAStartOfLineNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (curInd == 0 || str[curInd - 1] == '\n' || str[curInd - 1] == '\r')
+ {
+ return next->match(str, matcher, curInd);
+ }
+ return -1;
+}
+
+// NFAEndOfLineNode
+
+NFAEndOfLineNode::NFAEndOfLineNode() { }
+int NFAEndOfLineNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (curInd >= (int)str.size() || str[curInd] == '\n' || str[curInd] == '\r')
+ {
+ return next->match(str, matcher, curInd);
+ }
+ return -1;
+}
+
+// NFAReferenceNode
+
+NFAReferenceNode::NFAReferenceNode(const int groupIndex) : gi(groupIndex) { }
+int NFAReferenceNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int len = matcher->ends[gi] - matcher->starts[gi];
+ int ni = -1;
+ if (gi < 1 || matcher->ends[gi] < matcher->starts[gi] || len == 0) ni = curInd;
+ else if (curInd + len > (int)str.size()) return -1;
+ else if (str.substr(curInd, len) != str.substr(matcher->starts[gi], len)) return -1;
+ else ni = curInd + len;
+
+ return next->match(str, matcher, ni);
+}
+
+// NFAStartOfInputNode
+
+NFAStartOfInputNode::NFAStartOfInputNode() { }
+int NFAStartOfInputNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (curInd == 0) return next->match(str, matcher, curInd);
+ return -1;
+}
+
+// NFAEndOfInputNode
+
+NFAEndOfInputNode::NFAEndOfInputNode(const bool lookForTerm) : term(lookForTerm) { }
+int NFAEndOfInputNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int len = (int)str.size();
+ if (curInd == len) return next->match(str, matcher, curInd);
+ else if (term)
+ {
+ if (curInd == len - 1 && (str[curInd] == '\r' || str[curInd] == '\n'))
+ {
+ return next->match(str, matcher, curInd);
+ }
+ else if (curInd == len - 2 && str.substr(curInd, 2) == "\r\n")
+ {
+ return next->match(str, matcher, curInd);
+ }
+ }
+ return -1;
+}
+
+// NFAWordBoundaryNode
+
+NFAWordBoundaryNode::NFAWordBoundaryNode(const bool positive) : pos(positive) { }
+int NFAWordBoundaryNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ #define is_alpha(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z'))
+
+ int len = (int)str.size();
+ bool ok = 0;
+ char c1 = (curInd - 1 < len) ? str[curInd - 1] : -1;
+ char c2 = (curInd < len) ? str[curInd ] : -1;
+
+ if (curInd == len) return next->match(str, matcher, curInd);
+ if (is_alpha(c1) ^ is_alpha(c2)) ok = 1;
+ if (ok && pos) return next->match(str, matcher, curInd);
+ return -1;
+
+ #undef is_alpha
+}
+
+// NFAEndOfMatchNode
+
+NFAEndOfMatchNode::NFAEndOfMatchNode() { }
+int NFAEndOfMatchNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ if (curInd == matcher->lm) return next->match(str, matcher, curInd);
+ return -1;
+}
+
+// NFAGroupHeadNode
+
+NFAGroupHeadNode::NFAGroupHeadNode(const int groupIndex) : gi(groupIndex) { }
+int NFAGroupHeadNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int ret, o = matcher->starts[gi];
+
+ matcher->starts[gi] = curInd;
+ ret = next->match(str, matcher, curInd);
+ if (ret < 0) matcher->starts[gi] = o;
+
+ return ret;
+}
+
+// NFAGroupTailNode
+
+NFAGroupTailNode::NFAGroupTailNode(const int groupIndex) : gi(groupIndex) { }
+int NFAGroupTailNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int ret, o = matcher->ends[gi];
+
+ matcher->ends[gi] = curInd;
+ ret = next->match(str, matcher, curInd);
+ if (ret < 0) matcher->ends[gi] = o;
+
+ return ret;
+}
+
+// NFAGroupLoopPrologueNode
+
+NFAGroupLoopPrologueNode::NFAGroupLoopPrologueNode(const int groupIndex) : gi(groupIndex) { }
+int NFAGroupLoopPrologueNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int ret, o1 = matcher->groups[gi], o2 = matcher->groupPos[gi], o3 = matcher->groupIndeces[gi];
+
+ matcher->groups[gi] = 0;
+ matcher->groupPos[gi] = 0;
+ matcher->groupIndeces[gi] = -1;
+ ret = next->match(str, matcher, curInd);
+ if (ret < 0)
+ {
+ matcher->groups[gi] = o1;
+ matcher->groupPos[gi] = o2;
+ matcher->groupIndeces[gi] = o3;
+ }
+
+ return ret;
+}
+
+// NFAGroupLoopNode
+
+NFAGroupLoopNode::NFAGroupLoopNode(NFANode * internal, const int minMatch, const int maxMatch,
+ const int groupIndex, const int matchType)
+{
+ inner = internal;
+ min = minMatch;
+ max = maxMatch;
+ gi = groupIndex;
+ type = matchType;
+}
+void NFAGroupLoopNode::findAllNodes(std::map<NFANode*, bool> & soFar)
+{
+ if (inner) inner->findAllNodes(soFar);
+ NFANode::findAllNodes(soFar);
+}
+int NFAGroupLoopNode::match(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ bool b = (curInd > matcher->groupIndeces[gi]);
+
+ if (b && matcher->groups[gi] < min)
+ {
+ ++matcher->groups[gi];
+ int o = matcher->groupIndeces[gi];
+ matcher->groupIndeces[gi] = curInd;
+ int ret = inner->match(str, matcher, curInd);
+ if (ret < 0)
+ {
+ matcher->groupIndeces[gi] = o;
+ --matcher->groups[gi];
+ }
+ return ret;
+ }
+ else if (!b || matcher->groups[gi] >= max)
+ {
+ return next->match(str, matcher, curInd);
+ }
+ else
+ {
+ switch (type)
+ {
+ case 0: return matchGreedy(str, matcher, curInd);
+ case 1: return matchLazy(str, matcher, curInd);
+ case 2: return matchPossessive(str, matcher, curInd);
+ }
+ }
+ return -1;
+}
+int NFAGroupLoopNode::matchGreedy(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int o = matcher->groupIndeces[gi]; // save our info for backtracking
+ matcher->groupIndeces[gi] = curInd; // move along
+ ++matcher->groups[gi];
+ int ret = inner->match(str, matcher, curInd); // match internally
+ if (ret < 0)
+ { // if we failed, then restore info and match next
+ --matcher->groups[gi];
+ matcher->groupIndeces[gi] = o;
+ ret = next->match(str, matcher, curInd);
+ }
+ return ret;
+}
+int NFAGroupLoopNode::matchLazy(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int ret = next->match(str, matcher, curInd); // be lazy, just go on
+ if (ret < 0)
+ {
+ int o = matcher->groupIndeces[gi]; // save info for backtracking
+ matcher->groupIndeces[gi] = curInd; // advance our position
+ ++matcher->groups[gi];
+ ret = inner->match(str, matcher, curInd); // match our internal stuff
+ if (ret < 0) // if we failed, then restore the info
+ {
+ --matcher->groups[gi];
+ matcher->groupIndeces[gi] = o;
+ }
+ }
+ return ret;
+}
+int NFAGroupLoopNode::matchPossessive(const std::string & str, Matcher * matcher, const int curInd) const
+{
+ int o = matcher->groupIndeces[gi]; // save info for backtracking
+ matcher->groupPos[gi] = matcher->groups[gi]; // set a flag stating we have matcher at least this much
+ matcher->groupIndeces[gi] = curInd; // move along
+ ++matcher->groups[gi];
+ int ret = inner->match(str, matcher, curInd); // try and match again
+ if (ret < 0)
+ { // if we fail, back off, but to an extent
+ --matcher->groups[gi];
+ matcher->groupIndeces[gi] = o;
+ if (matcher->groups[gi] == matcher->groupPos[gi]) ret = next->match(str, matcher, curInd);
+ }
+ return ret;
+}
diff --git a/support/highlight/src/core/re/Pattern.h b/support/highlight/src/core/re/Pattern.h
new file mode 100644
index 0000000000..a88974194c
--- /dev/null
+++ b/support/highlight/src/core/re/Pattern.h
@@ -0,0 +1,1658 @@
+#ifndef __PATTERN_H__
+#define __PATTERN_H__
+
+#include <vector>
+#include <string>
+#include <map>
+
+class Matcher;
+class NFANode;
+class NFAQuantifierNode;
+
+/**
+ This pattern class is very similar in functionality to Java's
+ java.util.regex.Pattern class. The pattern class represents an immutable
+ regular expression object. Instead of having a single object contain both the
+ regular expression object and the matching object, instead the two objects are
+ split apart. The {@link Matcher Matcher} class represents the maching
+ object.
+
+ The Pattern class works primarily off of "compiled" patterns. A typical
+ instantiation of a regular expression looks like:
+
+ <pre>
+ Pattern * p = Pattern::compile("a*b");
+ Matcher * m = p->createMatcher("aaaaaab");
+ if (m->matches()) ...
+ </pre>
+
+ However, if you do not need to use a pattern more than once, it is often times
+ okay to use the Pattern's static methods insteads. An example looks like this:
+
+ <pre>
+ if (Pattern::matches("a*b", "aaaab")) { ... }
+ </pre>
+
+ This class does not currently support unicode. The unicode update for this
+ class is coming soon.
+
+ This class is partially immutable. It is completely safe to call createMatcher
+ concurrently in different threads, but the other functions (e.g. split) should
+ not be called concurrently on the same <code>Pattern</code>.
+
+ <table border="0" cellpadding="1" cellspacing="0">
+ <tr align="left" bgcolor="#CCCCFF">
+ <td>
+ <b>Construct</b>
+ </td>
+ <td>
+ <b>Matches</b>
+ </th>
+ </tr>
+ <tr>
+ <td colspan="2">
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <b>Characters</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x</i></code>
+ </td>
+ <td>
+ The character <code><i>x</i></code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\\</code>
+ </td>
+ <td>
+ The character <code>\</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\0<i>nn</i></code>
+ </td>
+ <td>
+ The character with octal ASCII value <code><i>nn</i></code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\0<i>nnn</i></code>
+ </td>
+ <td>
+ The character with octal ASCII value <code><i>nnn</i></code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\x<i>hh</i></code>
+ </td>
+ <td>
+ The character with hexadecimal ASCII value <code><i>hh</i></code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\t</code>
+ </td>
+ <td>
+ A tab character
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\r</code>
+ </td>
+ <td>
+ A carriage return character
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\n</code>
+ </td>
+ <td>
+ A new-line character
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>Character Classes</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>[abc]</code>
+ </td>
+ <td>
+ Either <code>a</code>, <code>b</code>, or <code>c</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>[^abc]</code>
+ </td>
+ <td>
+ Any character but <code>a</code>, <code>b</code>, or <code>c</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>[a-zA-Z]</code>
+ </td>
+ <td>
+ Any character ranging from <code>a</code> thru <code>z</code>, or
+ <code>A</code> thru <code>Z</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>[^a-zA-Z]</code>
+ </td>
+ <td>
+ Any character except those ranging from <code>a</code> thru
+ <code>z</code>, or <code>A</code> thru <code>Z</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>[a\-z]</code>
+ </td>
+ <td>
+ Either <code>a</code>, <code>-</code>, or <code>z</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>[a-z[A-Z]]</code>
+ </td>
+ <td>
+ Same as <code>[a-zA-Z]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>[a-z&&[g-i]]</code>
+ </td>
+ <td>
+ Any character in the intersection of <code>a-z</code> and
+ <code>g-i</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>[a-z&&[^g-i]]</code>
+ </td>
+ <td>
+ Any character in <code>a-z</code> and not in <code>g-i</code>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <b>Prefefined character classes</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><b>.</b></code>
+ </td>
+ <td>
+ Any character. Multiline matching must be compiled into the pattern for
+ <code><b>.</b></code> to match a <code>\r</code> or a <code>\n</code>.
+ Even if multiline matching is enabled, <code><b>.</b></code> will not
+ match a <code>\r\n</code>, only a <code>\r</code> or a <code>\n</code>.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\d</code>
+ </td>
+ <td>
+ <code>[0-9]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\D</code>
+ </td>
+ <td>
+ <code>[^\d]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\s</code>
+ </td>
+ <td>
+ <code>[&nbsp;\t\r\n\x0B]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\S</code>
+ </td>
+ <td>
+ <code>[^\s]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\w</code>
+ </td>
+ <td>
+ <code>[a-zA-Z0-9_]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\W</code>
+ </td>
+ <td>
+ <code>[^\w]</code>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <b>POSIX character classes
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\p{Lower}</code>
+ </td>
+ <td>
+ <code>[a-z]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\p{Upper}</code>
+ </td>
+ <td>
+ <code>[A-Z]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\p{ASCII}</code>
+ </td>
+ <td>
+ <code>[\x00-\x7F]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\p{Alpha}</code>
+ </td>
+ <td>
+ <code>[a-zA-Z]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\p{Digit}</code>
+ </td>
+ <td>
+ <code>[0-9]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\p{Alnum}</code>
+ </td>
+ <td>
+ <code>[\w&&[^_]]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\p{Punct}</code>
+ </td>
+ <td>
+ <code>[!"#$%&'()*+,-./:;&lt;=&gt;?@[\]^_`{|}~]</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\p{XDigit}</code>
+ </td>
+ <td>
+ <code>[a-fA-F0-9]</code>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <b>Boundary Matches</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>^</code>
+ </td>
+ <td>
+ The beginning of a line. Also matches the beginning of input.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>$</code>
+ </td>
+ <td>
+ The end of a line. Also matches the end of input.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\b</code>
+ </td>
+ <td>
+ A word boundary
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\B</code>
+ </td>
+ <td>
+ A non word boundary
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\A</code>
+ </td>
+ <td>
+ The beginning of input
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\G</code>
+ </td>
+ <td>
+ The end of the previous match. Ensures that a "next" match will only
+ happen if it begins with the character immediately following the end of
+ the "current" match.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\Z</code>
+ </td>
+ <td>
+ The end of input. Will also match if there is a single trailing
+ <code>\r\n</code>, a single trailing <code>\r</code>, or a single
+ trailing <code>\n</code>.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\z</code>
+ </td>
+ <td>
+ The end of input
+ </td>
+ </tr>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <b>Greedy Quantifiers</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x?</i></code>
+ </td>
+ <td>
+ <i>x</i>, either zero times or one time
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x*</i></code>
+ </td>
+ <td>
+ <i>x</i>, zero or more times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x+</i></code>
+ </td>
+ <td>
+ <i>x</i>, one or more times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{n}</i></code>
+ </td>
+ <td>
+ <i>x</i>, exactly n times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{n,}</i></code>
+ </td>
+ <td>
+ <i>x</i>, at least <code><i>n</i></code> times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{,m}</i></code>
+ </td>
+ <td>
+ <i>x</i>, at most <code><i>m</i></code> times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{n,m}</i></code>
+ </td>
+ <td>
+ <i>x</i>, at least <code><i>n</i></code> times and at most
+ <code><i>m</i></code> times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <b>Possessive Quantifiers</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x?+</i></code>
+ </td>
+ <td>
+ <i>x</i>, either zero times or one time
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x*+</i></code>
+ </td>
+ <td>
+ <i>x</i>, zero or more times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x++</i></code>
+ </td>
+ <td>
+ <i>x</i>, one or more times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{n}+</i></code>
+ </td>
+ <td>
+ <i>x</i>, exactly n times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{n,}+</i></code>
+ </td>
+ <td>
+ <i>x</i>, at least <code><i>n</i></code> times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{,m}+</i></code>
+ </td>
+ <td>
+ <i>x</i>, at most <code><i>m</i></code> times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{n,m}+</i></code>
+ </td>
+ <td>
+ <i>x</i>, at least <code><i>n</i></code> times and at most
+ <code><i>m</i></code> times
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <b>Reluctant Quantifiers</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x??</i></code>
+ </td>
+ <td>
+ <i>x</i>, either zero times or one time
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x*?</i></code>
+ </td>
+ <td>
+ <i>x</i>, zero or more times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x+?</i></code>
+ </td>
+ <td>
+ <i>x</i>, one or more times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{n}?</i></code>
+ </td>
+ <td>
+ <i>x</i>, exactly n times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{n,}?</i></code>
+ </td>
+ <td>
+ <i>x</i>, at least <code><i>n</i></code> times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{,m}?</i></code>
+ </td>
+ <td>
+ <i>x</i>, at most <code><i>m</i></code> times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x{n,m}?</i></code>
+ </td>
+ <td>
+ <i>x</i>, at least <code><i>n</i></code> times and at most
+ <code><i>m</i></code> times
+ </td>
+ </tr>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <b>Operators</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>xy</i></code>
+ </td>
+ <td>
+ <code><i>x</i></code> then <code><i>y</i></code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><i>x</i></code>|<code><i>y</i></code>
+ </td>
+ <td>
+ <code><i>x</i></code> or <code><i>y</i></code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>(<i>x</i>)</code>
+ </td>
+ <td>
+ <code><i>x</i></code> as a capturing group
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <b>Quoting</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\Q</code>
+ </td>
+ <td>
+ Nothing, but treat every character (including \s) literally until a
+ matching <code>\E</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>\E</code>
+ </td>
+ <td>
+ Nothing, but ends its matching <code>\Q</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <b>Special Constructs</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>(?:<i>x</i>)</code>
+ </td>
+ <td>
+ <code><i>x</i></code>, but not as a capturing group
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>(?=<i>x</i>)</code>
+ </td>
+ <td>
+ <code><i>x</i></code>, via positive lookahead. This means that the
+ expression will match only if it is trailed by <code><i>x</i></code>.
+ It will not "eat" any of the characters matched by
+ <code><i>x</i></code>.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>(?!<i>x</i>)</code>
+ </td>
+ <td>
+ <code><i>x</i></code>, via negative lookahead. This means that the
+ expression will match only if it is not trailed by
+ <code><i>x</i></code>. It will not "eat" any of the characters
+ matched by <code><i>x</i></code>.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>(?<=<i>x</i>)</code>
+ </td>
+ <td>
+ <code><i>x</i></code>, via positive lookbehind. <code><i>x</i></code>
+ cannot contain any quantifiers.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>(?<!<i>x</i>)</code>
+ </td>
+ <td>
+ <code><i>x</i></code>, via negative lookbehind. <code><i>x</i></code>
+ cannot contain any quantifiers.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>(?><i>x</i>)</code>
+ </td>
+ <td>
+ <code><i>x</i>{1}+</code>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <b>Registered Expression Matching</b>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>{<i>x</i>}</code>
+ </td>
+ <td>
+ The registered pattern <code><i>x</i></code>
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <i>Begin Text Extracted And Modified From java.util.regex.Pattern documentation</i>
+
+ <h4> Backslashes, escapes, and quoting </h4>
+
+ <p> The backslash character (<tt>'\'</tt>) serves to introduce escaped
+ constructs, as defined in the table above, as well as to quote characters
+ that otherwise would be interpreted as unescaped constructs. Thus the
+ expression <tt>\\</tt> matches a single backslash and <tt>\{</tt> matches a
+ left brace.
+
+ <p> It is an error to use a backslash prior to any alphabetic character that
+ does not denote an escaped construct; these are reserved for future
+ extensions to the regular-expression language. A backslash may be used
+ prior to a non-alphabetic character regardless of whether that character is
+ part of an unescaped construct.
+
+ <p>It is necessary to double backslashes in string literals that represent
+ regular expressions to protect them from interpretation by a compiler. The
+ string literal <tt>"&#92;b"</tt>, for example, matches a single backspace
+ character when interpreted as a regular expression, while
+ <tt>"&#92;&#92;b"</tt> matches a word boundary. The string litera
+ <tt>"&#92;(hello&#92;)"</tt> is illegal and leads to a compile-time error;
+ in order to match the string <tt>(hello)</tt> the string literal
+ <tt>"&#92;&#92;(hello&#92;&#92;)"</tt> must be used.
+
+ <h4> Character Classes </h4>
+
+ <p> Character classes may appear within other character classes, and
+ may be composed by the union operator (implicit) and the intersection
+ operator (<tt>&amp;&amp;</tt>).
+ The union operator denotes a class that contains every character that is
+ in at least one of its operand classes. The intersection operator
+ denotes a class that contains every character that is in both of its
+ operand classes.
+
+ <p> The precedence of character-class operators is as follows, from
+ highest to lowest:
+
+ <blockquote><table border="0" cellpadding="1" cellspacing="0"
+ summary="Precedence of character class operators.">
+
+ <tr><th>1&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <td>Literal escape&nbsp;&nbsp;&nbsp;&nbsp;</td>
+ <td><tt>\x</tt></td></tr>
+ <tr><th>2&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <td>Range</td>
+ <td><tt>a-z</tt></td></tr>
+ <tr><th>3&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <td>Grouping</td>
+ <td><tt>[...]</tt></td></tr>
+ <tr><th>4&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <td>Intersection</td>
+ <td><tt>[a-z&&[aeiou]]</tt></td></tr>
+ <tr><th>5&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <td>Union</td>
+ <td><tt>[a-e][i-u]<tt></td></tr>
+ </table></blockquote>
+
+ <p> Note that a different set of metacharacters are in effect inside
+ a character class than outside a character class. For instance, the
+ regular expression <tt>.</tt> loses its special meaning inside a
+ character class, while the expression <tt>-</tt> becomes a range
+ forming metacharacter.
+
+ <a name="lt">
+
+ <a name="cg">
+ <h4> Groups and capturing </h4>
+
+ <p> Capturing groups are numbered by counting their opening parentheses from
+ left to right. In the expression <tt>((A)(B(C)))</tt>, for example, there
+ are four such groups: </p>
+
+ <blockquote><table cellpadding=1 cellspacing=0 summary="Capturing group numberings">
+
+ <tr><th>1&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <td><tt>((A)(B(C)))</tt></td></tr>
+ <tr><th>2&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <td><tt>(A)</tt></td></tr>
+ <tr><th>3&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <td><tt>(B(C))</tt></td></tr>
+
+ <tr><th>4&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ <td><tt>(C)</tt></td></tr>
+ </table></blockquote>
+
+ <p> Group zero always stands for the entire expression.
+
+ <p> Capturing groups are so named because, during a match, each subsequence
+ of the input sequence that matches such a group is saved. The captured
+ subsequence may be used later in the expression, via a back reference, and
+ may also be retrieved from the matcher once the match operation is complete.
+
+ <p> The captured input associated with a group is always the subsequence
+ that the group most recently matched. If a group is evaluated a second time
+ because of quantification then its previously-captured value, if any, will
+ be retained if the second evaluation fails. Matching the string
+ <tt>"aba"</tt> against the expression <tt>(a(b)?)+</tt>, for example, leaves
+ group two set to <tt>"b"</tt>. All captured input is discarded at the
+ beginning of each match.
+
+ <p> Groups beginning with <tt>(?</tt> are pure, <i>non-capturing</i> groups
+ that do not capture text and do not count towards the group total.
+
+
+ <h4> Unicode support </h4>
+
+ <p> Coming Soon.
+
+ <h4> Comparison to Perl 5 </h4>
+
+ <p>The <code>Pattern</code> engine performs traditional NFA-based matching
+ with ordered alternation as occurs in Perl 5.
+
+ <p> Perl constructs not supported by this class: </p>
+
+ <ul>
+
+ <li><p> The conditional constructs <tt>(?{</tt><i>X</i><tt>})</tt> and
+ <tt>(?(</tt><i>condition</i><tt>)</tt><i>X</i><tt>|</tt><i>Y</i><tt>)</tt>,
+ </p></li>
+
+ <li><p> The embedded code constructs <tt>(?{</tt><i>code</i><tt>})</tt>
+ and <tt>(??{</tt><i>code</i><tt>})</tt>,</p></li>
+
+ <li><p> The embedded comment syntax <tt>(?#comment)</tt>, and </p></li>
+
+ <li><p> The preprocessing operations <tt>\l</tt> <tt>&#92;u</tt>,
+ <tt>\L</tt>, and <tt>\U</tt>. </p></li>
+
+ <li><p> Embedded flags</p></li>
+
+ </ul>
+
+ <p> Constructs supported by this class but not by Perl: </p>
+
+ <ul>
+
+ <li><p> Possessive quantifiers, which greedily match as much as they can
+ and do not back off, even when doing so would allow the overall match to
+ succeed. </p></li>
+
+ <li><p> Character-class union and intersection as described
+ above.</p></li>
+
+ </ul>
+
+ <p> Notable differences from Perl: </p>
+
+ <ul>
+
+ <li><p> In Perl, <tt>\1</tt> through <tt>\9</tt> are always interpreted
+ as back references; a backslash-escaped number greater than <tt>9</tt> is
+ treated as a back reference if at least that many subexpressions exist,
+ otherwise it is interpreted, if possible, as an octal escape. In this
+ class octal escapes must always begin with a zero. In this class,
+ <tt>\1</tt> through <tt>\9</tt> are always interpreted as back
+ references, and a larger number is accepted as a back reference if at
+ least that many subexpressions exist at that point in the regular
+ expression, otherwise the parser will drop digits until the number is
+ smaller or equal to the existing number of groups or it is one digit.
+ </p></li>
+
+ <li><p> Perl uses the <tt>g</tt> flag to request a match that resumes
+ where the last match left off. This functionality is provided implicitly
+ by the <CODE>Matcher</CODE> class: Repeated invocations of the
+ <code>find</code> method will resume where the last match left off,
+ unless the matcher is reset. </p></li>
+
+ <li><p> Perl is forgiving about malformed matching constructs, as in the
+ expression <tt>*a</tt>, as well as dangling brackets, as in the
+ expression <tt>abc]</tt>, and treats them as literals. This
+ class also strict and will not compile a pattern when dangling characters
+ are encountered.</p></li>
+
+ </ul>
+
+
+ <p> For a more precise description of the behavior of regular expression
+ constructs, please see <a href="http://www.oreilly.com/catalog/regex2/">
+ <i>Mastering Regular Expressions, 2nd Edition</i>, Jeffrey E. F. Friedl,
+ O'Reilly and Associates, 2002.</a>
+ </p>
+ <P>
+
+ <i>End Text Extracted And Modified From java.util.regex.Pattern documentation</i>
+
+ <hr>
+
+ @author Jeffery Stuart
+ @since March 2003, Stable Since November 2004
+ @version 1.04
+ @memo A class used to represent "PERL 5"-ish regular expressions
+ */
+class Pattern
+{
+ friend class Matcher;
+ friend class NFANode;
+ friend class NFAQuantifierNode;
+ private:
+ /**
+ This constructor should not be called directly. Those wishing to use the
+ Pattern class should instead use the {@link compile compile} method.
+
+ @param rhs The pattern to compile
+ @memo Creates a new pattern from the regular expression in <code>rhs</code>.
+ */
+ Pattern(const std::string & rhs);
+ protected:
+ /**
+ This currently is not used, so don't try to do anything with it.
+ @memo Holds all the compiled patterns for quick access.
+ */
+ static std::map<std::string, Pattern *> compiledPatterns;
+ /**
+ Holds all of the registered patterns as strings. Due to certain problems
+ with compilation of patterns, especially with capturing groups, this seemed
+ to be the best way to do it.
+ */
+ static std::map<std::string, std::pair<std::string, unsigned long> > registeredPatterns;
+ protected:
+ /**
+ Holds all the NFA nodes used. This makes deletion of a pattern, as well as
+ clean-up from an unsuccessful compile much easier and faster.
+ */
+ std::map<NFANode*, bool> nodes;
+ /**
+ Used when methods like split are called. The matcher class uses a lot of
+ dynamic memeory, so having an instance increases speedup of certain
+ operations.
+ */
+ Matcher * matcher;
+ /**
+ The front node of the NFA.
+ */
+ NFANode * head;
+ /**
+ The actual regular expression we rerpesent
+ */
+ std::string pattern;
+ /**
+ Flag used during compilation. Once the pattern is successfully compiled,
+ <code>error</code> is no longer used.
+ */
+ bool error;
+ /**
+ Used during compilation to keep track of the current index into
+ <code>{@link pattern pattern}<code>. Once the pattern is successfully
+ compiled, <code>error</code> is no longer used.
+ */
+ int curInd;
+ /**
+ The number of capture groups this contains.
+ */
+ int groupCount;
+ /**
+ The number of non-capture groups this contains.
+ */
+ int nonCapGroupCount;
+ /**
+ The flags specified when this was compiled.
+ */
+ unsigned long flags;
+ protected:
+ /**
+ Raises an error during compilation. Compilation will cease at that point
+ and compile will return <code>NULL</code>.
+ */
+ void raiseError();
+ /**
+ Convenience function for registering a node in <code>nodes</code>.
+ @param node The node to register
+ @return The registered node
+ */
+ NFANode * registerNode(NFANode * node);
+
+ /**
+ Calculates the union of two strings. This function will first sort the
+ strings and then use a simple selection algorithm to find the union.
+ @param s1 The first "class" to union
+ @param s2 The second "class" to union
+ @return A new string containing all unique characters. Each character
+ must have appeared in one or both of <code>s1</code> and
+ <code>s2</code>.
+ */
+ std::string classUnion (std::string s1, std::string s2) const;
+ /**
+ Calculates the intersection of two strings. This function will first sort
+ the strings and then use a simple selection algorithm to find the
+ intersection.
+ @param s1 The first "class" to intersect
+ @param s2 The second "class" to intersect
+ @return A new string containing all unique characters. Each character
+ must have appeared both <code>s1</code> and <code>s2</code>.
+ */
+ std::string classIntersect (std::string s1, std::string s2) const;
+ /**
+ Calculates the negation of a string. The negation is the set of all
+ characters between <code>\x00</code> and <code>\xFF</code> not
+ contained in <code>s1</code>.
+ @param s1 The "class" to be negated.
+ @param s2 The second "class" to intersect
+ @return A new string containing all unique characters. Each character
+ must have appeared both <code>s1</code> and <code>s2</code>.
+ */
+ std::string classNegate (std::string s1) const;
+ /**
+ Creates a new "class" representing the range from <code>low</code> thru
+ <code>hi</code>. This function will wrap if <code>low</code> &gt;
+ <code>hi</code>. This is a feature, not a buf. Sometimes it is useful
+ to be able to say [\x70-\x10] instead of [\x70-\x7F\x00-\x10].
+ @param low The beginning character
+ @param hi The ending character
+ @return A new string containing all the characters from low thru hi.
+ */
+ std::string classCreateRange(char low, char hi) const;
+
+ /**
+ Extracts a decimal number from the substring of member-variable
+ <code>{@link pattern pattern}<code> starting at <code>start</code> and
+ ending at <code>end</code>.
+ @param start The starting index in <code>{@link pattern pattern}<code>
+ @param end The last index in <code>{@link pattern pattern}<code>
+ @return The decimal number in <code>{@link pattern pattern}<code>
+ */
+ int getInt(int start, int end);
+ /**
+ Parses a <code>{n,m}</code> string out of the member-variable
+ <code>{@link pattern pattern}<code> stores the result in <code>sNum</code>
+ and <code>eNum</code>.
+ @param sNum Output parameter. The minimum number of matches required
+ by the curly quantifier are stored here.
+ @param eNum Output parameter. The maximum number of matches allowed
+ by the curly quantifier are stored here.
+ @return Success/Failure. Fails when the curly does not have the proper
+ syntax
+ */
+ bool quantifyCurly(int & sNum, int & eNum);
+ /**
+ Tries to quantify the currently parsed group. If the group being parsed
+ is indeed quantified in the member-variable
+ <code>{@link pattern pattern}<code>, then the NFA is modified accordingly.
+ @param start The starting node of the current group being parsed
+ @param stop The ending node of the current group being parsed
+ @param gn The group number of the current group being parsed
+ @return The node representing the starting node of the group. If the
+ group becomes quantified, then this node is not necessarily
+ a GroupHead node.
+ */
+ NFANode * quantifyGroup(NFANode * start, NFANode * stop, const int gn);
+
+ /**
+ Tries to quantify the last parsed expression. If the character was indeed
+ quantified, then the NFA is modified accordingly.
+ @param newNode The recently created expression node
+ @return The node representing the last parsed expression. If the
+ expression was quantified, <code>return value != newNode</code>
+ */
+ NFANode * quantify(NFANode * newNode);
+ /**
+ Parses the current class being examined in
+ <code>{@link pattern pattern}</code>.
+ @return A string of unique characters contained in the current class being
+ parsed
+ */
+ std::string parseClass();
+ /**
+ Parses the current POSIX class being examined in
+ <code>{@link pattern pattern}</code>.
+ @return A string of unique characters representing the POSIX class being
+ parsed
+ */
+ std::string parsePosix();
+ /**
+ Returns a string containing the octal character being parsed
+ @return The string contained the octal value being parsed
+ */
+ std::string parseOctal();
+ /**
+ Returns a string containing the hex character being parsed
+ @return The string contained the hex value being parsed
+ */
+ std::string parseHex();
+ /**
+ Returns a new node representing the back reference being parsed
+ @return The new node representing the back reference being parsed
+ */
+ NFANode * parseBackref();
+ /**
+ Parses the escape sequence currently being examined. Determines if the
+ escape sequence is a class, a single character, or the beginning of a
+ quotation sequence.
+ @param inv Output parameter. Whether or not to invert the returned class
+ @param quo Output parameter. Whether or not this sequence starts a
+ quotation.
+ @return The characters represented by the class
+ */
+ std::string parseEscape(bool & inv, bool & quo);
+ /**
+ Parses a supposed registered pattern currently under compilation. If the
+ sequence of characters does point to a registered pattern, then the
+ registered pattern is appended to <code>*end<code>. The registered pattern
+ is parsed with the current compilation flags.
+ @param end The ending node of the thus-far compiled pattern
+ @return The new end node of the current pattern
+ */
+ NFANode * parseRegisteredPattern(NFANode ** end);
+ /**
+ Parses a lookbehind expression. Appends the necessary nodes
+ <code>*end</code>.
+ @param pos Positive or negative look behind
+ @param end The ending node of the current pattern
+ @return The new end node of the current pattern
+ */
+ NFANode * parseBehind(const bool pos, NFANode ** end);
+ /**
+ Parses the current expression and tacks on nodes until a \E is found.
+ @return The end of the current pattern
+ */
+ NFANode * parseQuote();
+ /**
+ Parses <code>{@link pattern pattern}</code>. This function is called
+ recursively when an or (<code>|</code>) or a group is encountered.
+ @param inParen Are we currently parsing inside a group
+ @param inOr Are we currently parsing one side of an or (<code>|</code>)
+ @param end The end of the current expression
+ @return The starting node of the NFA constructed from this parse
+ */
+ NFANode * parse(const bool inParen = 0, const bool inOr = 0, NFANode ** end = NULL);
+ public:
+ /// We should match regardless of case
+ const static unsigned long CASE_INSENSITIVE;
+ /// We are implicitly quoted
+ const static unsigned long LITERAL;
+ /// @memo We should treat a <code><b>.</b></code> as [\x00-\x7F]
+ const static unsigned long DOT_MATCHES_ALL;
+ /** <code>^</code> and <code>$</code> should anchor to the beginning and
+ ending of lines, not all input
+ */
+ const static unsigned long MULTILINE_MATCHING;
+ /** When enabled, only instances of <code>\n</codes> are recognized as
+ line terminators
+ */
+ const static unsigned long UNIX_LINE_MODE;
+ /// The absolute minimum number of matches a quantifier can match (0)
+ const static int MIN_QMATCH;
+ /// The absolute maximum number of matches a quantifier can match (0x7FFFFFFF)
+ const static int MAX_QMATCH;
+ public:
+ /**
+ Call this function to compile a regular expression into a
+ <code>Pattern</code> object. Special values can be assigned to
+ <code>mode</code> when certain non-standard behaviors are expected from
+ the <code>Pattern</code> object.
+ @param pattern The regular expression to compile
+ @param mode A bitwise or of flags signalling what special behaviors are
+ wanted from this <code>Pattern</code> object
+ @return If successful, <code>compile</code> returns a <code>Pattern</code>
+ pointer. Upon failure, <code>compile</code> returns
+ <code>NULL</code>
+ */
+ static Pattern * compile (const std::string & pattern,
+ const unsigned long mode = 0);
+ /**
+ Dont use this function. This function will compile a pattern, and cache
+ the result. This will eventually be used as an optimization when people
+ just want to call static methods using the same pattern over and over
+ instead of first compiling the pattern and then using the compiled
+ instance for matching.
+ @param pattern The regular expression to compile
+ @param mode A bitwise or of flags signalling what special behaviors are
+ wanted from this <code>Pattern</code> object
+ @return If successful, <code>compileAndKeep</code> returns a
+ <code>Pattern</code> pointer. Upon failure, <code>compile</code>
+ returns <code>NULL</code>.
+ */
+ static Pattern * compileAndKeep (const std::string & pattern,
+ const unsigned long mode = 0);
+
+ /**
+ Searches through <code>replace</code> and replaces all substrings matched
+ by <code>pattern</code> with <code>str</code>. <code>str</code> may
+ contain backreferences (e.g. <code>\1</code>) to capture groups. A typical
+ invocation looks like:
+ <p>
+ <code>
+ Pattern::replace("(a+)b(c+)", "abcccbbabcbabc", "\\2b\\1");
+ </code>
+ <p>
+ which would replace <code>abcccbbabcbabc</code> with
+ <code>cccbabbcbabcba</code>.
+ @param pattern The regular expression
+ @param str The replacement text
+ @param replacementText The string in which to perform replacements
+ @param mode The special mode requested of the <code>Pattern</code>
+ during the replacement process
+ @return The text with the replacement string substituted where necessary
+ */
+ static std::string replace (const std::string & pattern,
+ const std::string & str,
+ const std::string & replacementText,
+ const unsigned long mode = 0);
+
+ /**
+ Splits the specified string over occurrences of the specified pattern.
+ Empty strings can be optionally ignored. The number of strings returned is
+ configurable. A typical invocation looks like:
+ <p>
+ <code>
+ std::string str(strSize, '\0');<br>
+ FILE * fp = fopen(fileName, "r");<br>
+ fread((char*)str.data(), strSize, 1, fp);<br>
+ fclose(fp);<br>
+ <br>
+ std::vector&lt;std::string&gt; lines = Pattern::split("[\r\n]+", str, true);<br>
+ <br>
+ </code>
+
+ @param pattern The regular expression
+ @param replace The string to split
+ @param keepEmptys Whether or not to keep empty strings
+ @param limit The maximum number of splits to make
+ @param mode The special mode requested of the <code>Pattern</code>
+ during the split process
+ @return All substrings of <code>str</code> split across <code>pattern</code>.
+ */
+ static std::vector<std::string> split (const std::string & pattern,
+ const std::string & str,
+ const bool keepEmptys = 0,
+ const unsigned long limit = 0,
+ const unsigned long mode = 0);
+
+ /**
+ Finds all the instances of the specified pattern within the string. You
+ should be careful to only pass patterns with a minimum length of one. For
+ example, the pattern <code>a*</code> can be matched by an empty string, so
+ instead you should pass <code>a+</code> since at least one character must
+ be matched. A typical invocation of <code>findAll</code> looks like:
+ <p>
+ <code>
+ std::vector&lt;td::string&gt; numbers = Pattern::findAll("\\d+", string);
+ </code>
+ <p>
+
+ @param pattern The pattern for which to search
+ @param str The string to search
+ @param mode The special mode requested of the <code>Pattern</code>
+ during the find process
+ @return All instances of <code>pattern</code> in <code>str</code>
+ */
+ static std::vector<std::string> findAll (const std::string & pattern,
+ const std::string & str,
+ const unsigned long mode = 0);
+
+ /**
+ Determines if an entire string matches the specified pattern
+
+ @param pattern The pattern for to match
+ @param str The string to match
+ @param mode The special mode requested of the <code>Pattern</code>
+ during the replacement process
+ @return True if <code>str</code> is recognized by <code>pattern</code>
+ */
+ static bool matches (const std::string & pattern,
+ const std::string & str,
+ const unsigned long mode = 0);
+
+ /**
+ Registers a pattern under a specific name for use in later compilations.
+ A typical invocation and later use looks like:
+ <p>
+ <code>
+ Pattern::registerPattern("ip", "(?:\\d{1,3}\\.){3}\\d{1,3}");<br>
+ Pattern * p1 = Pattern::compile("{ip}:\\d+");<br>
+ Pattern * p2 = Pattern::compile("Connection from ({ip}) on port \\d+");<br>
+ </code>
+ <p>
+ Multiple calls to <code>registerPattern</code> with the same
+ <code>name</code> will result in the pattern getting overwritten.
+
+ @param name The name to give to the pattern
+ @param pattern The pattern to register
+ @param mode Any special flags to use when compiling pattern
+ @return Success/Failure. Fails only if <code>pattern</code> has invalid
+ syntax
+ */
+ static bool registerPattern(const std::string & name,
+ const std::string & pattern,
+ const unsigned long mode = 0);
+
+ /**
+ Clears the pattern registry
+ */
+ static void unregisterPatterns();
+ /**
+ Don't use
+ */
+ static void clearPatternCache();
+
+ /**
+ Searches through a string for the <code>n<sup>th</sup></code> match of the
+ given pattern in the string. Match indeces start at zero, not one.
+ A typical invocation looks like this:
+ <p>
+ <code>
+ std::pair&lt;std::string, int&gt; match = Pattern::findNthMatch("\\d{1,3}", "192.168.1.101:22", 1);<br>
+ printf("%s %i\n", match.first.c_str(), match.second);<br>
+ <br>
+ Output: 168 4<br>
+ <br>
+
+ @param pattern The pattern for which to search
+ @param str The string to search
+ @param matchNum Which match to find
+ @param mode Any special flags to use during the matching process
+ @return A string and an integer. The string is the string matched. The
+ integer is the starting location of the matched string in
+ <code>str</code>. You can check for success/failure by making sure
+ that the integer returned is greater than or equal to zero.
+ */
+ static std::pair<std::string, int> findNthMatch (const std::string & pattern,
+ const std::string & str,
+ const int matchNum,
+ const unsigned long mode = 0);
+ public:
+ /**
+ Deletes all NFA nodes allocated during compilation
+ */
+ ~Pattern();
+
+ std::string replace (const std::string & str,
+ const std::string & replacementText);
+ std::vector<std::string> split (const std::string & str, const bool keepEmptys = 0,
+ const unsigned long limit = 0);
+ std::vector<std::string> findAll (const std::string & str);
+ bool matches (const std::string & str);
+ /**
+ Returns the flags used during compilation of this pattern
+ @return The flags used during compilation of this pattern
+ */
+ unsigned long getFlags () const;
+ /**
+ Returns the regular expression this pattern represents
+ @return The regular expression this pattern represents
+ */
+ std::string getPattern () const;
+ /**
+ Creates a matcher object using the specified string and this pattern.
+ @param str The string to match against
+ @return A new matcher using object using this pattern and the specified
+ string
+ */
+ Matcher * createMatcher (const std::string & str);
+};
+
+class NFANode
+{
+ friend class Matcher;
+ public:
+ NFANode * next;
+ NFANode();
+ virtual ~NFANode();
+ virtual void findAllNodes(std::map<NFANode*, bool> & soFar);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const = 0;
+ inline virtual bool isGroupHeadNode() const { return false; }
+ inline virtual bool isStartOfInputNode() const { return false; }
+};
+class NFACharNode : public NFANode
+{
+ protected:
+ char ch;
+ public:
+ NFACharNode(const char c);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFACICharNode : public NFANode
+{
+ protected:
+ char ch;
+ public:
+ NFACICharNode(const char c);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAStartNode : public NFANode
+{
+ public:
+ NFAStartNode();
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAEndNode : public NFANode
+{
+ public:
+ NFAEndNode();
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAQuantifierNode : public NFANode
+{
+ public:
+ int min, max;
+ NFANode * inner;
+ virtual void findAllNodes(std::map<NFANode*, bool> & soFar);
+ NFAQuantifierNode(Pattern * pat, NFANode * internal,
+ const int minMatch = Pattern::MIN_QMATCH,
+ const int maxMatch = Pattern::MAX_QMATCH);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAGreedyQuantifierNode : public NFAQuantifierNode
+{
+ public:
+ NFAGreedyQuantifierNode(Pattern * pat, NFANode * internal,
+ const int minMatch = Pattern::MIN_QMATCH,
+ const int maxMatch = Pattern::MAX_QMATCH);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+ virtual int matchInternal(const std::string & str, Matcher * matcher, const int curInd, const int soFar) const;
+};
+class NFALazyQuantifierNode : public NFAQuantifierNode
+{
+ public:
+ NFALazyQuantifierNode(Pattern * pat, NFANode * internal,
+ const int minMatch = Pattern::MIN_QMATCH,
+ const int maxMatch = Pattern::MAX_QMATCH);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAPossessiveQuantifierNode : public NFAQuantifierNode
+{
+ public:
+ NFAPossessiveQuantifierNode(Pattern * pat, NFANode * internal,
+ const int minMatch = Pattern::MIN_QMATCH,
+ const int maxMatch = Pattern::MAX_QMATCH);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAAcceptNode : public NFANode
+{
+ public:
+ NFAAcceptNode();
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAClassNode : public NFANode
+{
+ public:
+ bool inv;
+ std::map<char, bool> vals;
+ NFAClassNode(const bool invert = 0);
+ NFAClassNode(const std::string & clazz, const bool invert);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFACIClassNode : public NFANode
+{
+ public:
+ bool inv;
+ std::map<char, bool> vals;
+ NFACIClassNode(const bool invert = 0);
+ NFACIClassNode(const std::string & clazz, const bool invert);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFASubStartNode : public NFANode
+{
+ public:
+ NFASubStartNode();
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAOrNode : public NFANode
+{
+ public:
+ NFANode * one;
+ NFANode * two;
+ NFAOrNode(NFANode * first, NFANode * second);
+ virtual void findAllNodes(std::map<NFANode*, bool> & soFar);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAQuoteNode : public NFANode
+{
+ public:
+ std::string qStr;
+ NFAQuoteNode(const std::string & quoted);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFACIQuoteNode : public NFANode
+{
+ public:
+ std::string qStr;
+ NFACIQuoteNode(const std::string & quoted);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFALookAheadNode : public NFANode
+{
+ public:
+ bool pos;
+ NFANode * inner;
+ NFALookAheadNode(NFANode * internal, const bool positive);
+ virtual void findAllNodes(std::map<NFANode*, bool> & soFar);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFALookBehindNode : public NFANode
+{
+ public:
+ bool pos;
+ std::string mStr;
+ NFALookBehindNode(const std::string & str, const bool positive);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAStartOfLineNode : public NFANode
+{
+ public:
+ NFAStartOfLineNode();
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAEndOfLineNode : public NFANode
+{
+ public:
+ NFAEndOfLineNode();
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAReferenceNode : public NFANode
+{
+ public:
+ int gi;
+ NFAReferenceNode(const int groupIndex);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAStartOfInputNode : public NFANode
+{
+ public:
+ NFAStartOfInputNode();
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+ inline virtual bool isStartOfInputNode() const { return true; }
+};
+class NFAEndOfInputNode : public NFANode
+{
+ public:
+ bool term;
+ NFAEndOfInputNode(const bool lookForTerm);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAWordBoundaryNode : public NFANode
+{
+ public:
+ bool pos;
+ NFAWordBoundaryNode(const bool positive);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAEndOfMatchNode : public NFANode
+{
+ public:
+ NFAEndOfMatchNode();
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAGroupHeadNode : public NFANode
+{
+ public:
+ int gi;
+ NFAGroupHeadNode(const int groupIndex);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+ inline virtual bool isGroupHeadNode() const { return true; }
+};
+class NFAGroupTailNode : public NFANode
+{
+ public:
+ int gi;
+ NFAGroupTailNode(const int groupIndex);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAGroupLoopPrologueNode : public NFANode
+{
+ public:
+ int gi;
+ NFAGroupLoopPrologueNode(const int groupIndex);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+class NFAGroupLoopNode : public NFANode
+{
+ public:
+ int gi, min, max, type;
+ NFANode * inner;
+ NFAGroupLoopNode(NFANode * internal, const int minMatch,
+ const int maxMatch, const int groupIndex, const int matchType);
+ virtual void findAllNodes(std::map<NFANode*, bool> & soFar);
+ virtual int match(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+ int matchGreedy(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+ int matchLazy(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+ int matchPossessive(const std::string & str, Matcher * matcher, const int curInd = 0) const;
+};
+
+#endif
+
diff --git a/support/highlight/src/core/rtfgenerator.cpp b/support/highlight/src/core/rtfgenerator.cpp
new file mode 100644
index 0000000000..dab2c805cc
--- /dev/null
+++ b/support/highlight/src/core/rtfgenerator.cpp
@@ -0,0 +1,363 @@
+/***************************************************************************
+ rtfcode.cpp - description
+ -------------------
+ begin : Die Jul 9 2002
+ copyright : (C) 2002-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <sstream>
+
+#include "charcodes.h"
+#include "version.h"
+#include "rtfgenerator.h"
+
+using namespace std;
+
+namespace highlight
+{
+
+ string RtfGenerator::getAttributes ( const ElementStyle & col )
+ {
+ stringstream s;
+ s << "\\red"<< col.getColour().getRed ( RTF )
+ << "\\green"<<col.getColour().getGreen ( RTF )
+ << "\\blue"<<col.getColour().getBlue ( RTF )
+ << ";";
+ return s.str();
+ }
+
+ string RtfGenerator::getOpenTag ( int styleNumber,const ElementStyle & elem )
+ {
+ ostringstream s;
+ s << "{";
+ if ( addCharStyles )
+ {
+ s<<"\\*\\cs"<< ( styleNumber+2 );
+ }
+ s << "\\cf"<< ( styleNumber+2 ) <<"{";
+
+ if ( elem.isBold() ) s << "\\b ";
+ if ( elem.isItalic() ) s << "\\i ";
+ if ( elem.isUnderline() ) s << "\\ul ";
+ return s.str();
+ }
+
+
+ string RtfGenerator::getCharStyle ( int styleNumber,const ElementStyle &elem,
+ const string&styleName )
+ {
+ ostringstream s;
+ s << "{\\*\\cs"<< ( styleNumber+2 ) <<"\\additive\\cf"<< ( styleNumber+2 )
+ << "\\f1\\fs";
+ int fontSize=0;
+ StringTools::str2num<int> ( fontSize, this->getBaseFontSize(), std::dec );
+ s << ( ( fontSize ) ? fontSize*2: 20 ); // RTF needs double amount
+ if ( elem.isBold() ) s << "\\b";
+ if ( elem.isItalic() ) s << "\\i";
+ if ( elem.isUnderline() ) s << "\\ul";
+ s << "\\sbasedon222\\snext0 "<< styleName << ";}\n";
+ return s.str();
+ }
+// {\*\cs2\additive\cf2\f1\fs20\sbasedon222\snext0 HL Default;}
+
+ string RtfGenerator::getCloseTag ( const ElementStyle &elem )
+ {
+ ostringstream s;
+ if ( elem.isBold() ) s << "\\b0 ";
+ if ( elem.isItalic() ) s << "\\i0 ";
+ if ( elem.isUnderline() ) s << "\\ul0 ";
+ s << "}}";
+ return s.str();
+ }
+
+ RtfGenerator::RtfGenerator()
+ : CodeGenerator ( RTF ),
+ pageSize ( "a4" ), // Default: DIN A4
+ addCharStyles ( false )
+ {
+ newLineTag = "}\\par\\pard\n\\cbpat1{";
+ spacer = " ";
+
+ // Page dimensions
+ psMap["a3"] = PageSize ( 16837,23811 );
+ psMap["a4"] = PageSize ( 11905,16837 );
+ psMap["a5"] = PageSize ( 8390,11905 );
+
+ psMap["b4"] = PageSize ( 14173,20012 );
+ psMap["b5"] = PageSize ( 9977,14173 );
+ psMap["b6"] = PageSize ( 7086,9977 );
+
+ psMap["letter"] = PageSize ( 12240,15840 );
+ psMap["legal"] = PageSize ( 12240,20163 );
+ }
+
+ RtfGenerator::~RtfGenerator()
+ {}
+
+ string RtfGenerator::getHeader()
+ {
+ return string();
+ }
+
+ void RtfGenerator::printBody()
+ {
+ *out << "{\\rtf1\\ansi\\uc0 \\deff1"
+ << "{\\fonttbl{\\f1\\fmodern\\fprq1\\fcharset0 " ;
+ *out << this->getBaseFont() ;
+ *out << ";}}"
+ << "{\\colortbl;";
+
+ *out << "\\red" << ( docStyle.getBgColour().getRed ( RTF ) );
+ *out << "\\green" << ( docStyle.getBgColour().getGreen ( RTF ) );
+ *out << "\\blue" << ( docStyle.getBgColour().getBlue ( RTF ) );
+ *out << ";";
+
+ *out << getAttributes ( docStyle.getDefaultStyle() );
+
+ *out << getAttributes ( docStyle.getStringStyle() );
+ *out << getAttributes ( docStyle.getNumberStyle() );
+ *out << getAttributes ( docStyle.getSingleLineCommentStyle() );
+
+ *out << getAttributes ( docStyle.getCommentStyle() );
+ *out << getAttributes ( docStyle.getEscapeCharStyle() );
+ *out << getAttributes ( docStyle.getDirectiveStyle() );
+
+ *out << getAttributes ( docStyle.getDirectiveStringStyle() );
+ *out << getAttributes ( docStyle.getLineStyle() );
+ *out << getAttributes ( docStyle.getSymbolStyle() );
+
+ /* For output formats which can refer to external styles it is more safe
+ to use the colour theme's keyword class names, since the language
+ definitions (which may change during a batch conversion) do not have to define
+ all keyword classes, that are needed to highlight all input files correctly.
+ It is ok for RTF to use the language definition's class names, because RTF
+ does not refer to external styles.
+ We cannot use the theme's class names, because KSIterator returns an
+ alphabetically ordered list, which is not good because RTF is dependent
+ on the order. We access the keyword style with an ID, which is calculated
+ ignoring the alphabetic order.
+ */
+ vector<string> keywordClasses = langInfo.getKeywordClasses();
+ for ( unsigned int i=0;i<keywordClasses.size();i++ )
+ {
+ *out << getAttributes ( docStyle.getKeywordStyle ( keywordClasses[i] ) );
+ }
+
+ *out << "}\n";
+
+ if ( addCharStyles )
+ {
+ *out << "{\\stylesheet{\n";
+ *out << getCharStyle ( STANDARD, docStyle.getDefaultStyle(), "HL Default" );
+ *out << getCharStyle ( STRING, docStyle.getStringStyle(), "HL String" );
+ *out << getCharStyle ( NUMBER, docStyle.getNumberStyle(), "HL Number" );
+ *out << getCharStyle ( SL_COMMENT, docStyle.getSingleLineCommentStyle(), "HL SL Comment" );
+ *out << getCharStyle ( ML_COMMENT, docStyle.getCommentStyle(), "HL ML Comment" );
+ *out << getCharStyle ( ESC_CHAR, docStyle.getEscapeCharStyle(), "HL Escape Character" );
+ *out << getCharStyle ( DIRECTIVE, docStyle.getDirectiveStyle(), "HL Directive" );
+ *out << getCharStyle ( DIRECTIVE_STRING, docStyle.getDirectiveStringStyle(), "HL Directive String" );
+ *out << getCharStyle ( LINENUMBER, docStyle.getLineStyle(), "HL Line" );
+ *out << getCharStyle ( SYMBOL, docStyle.getSymbolStyle(), "HL Symbol" );
+ char styleName[20];
+ for ( unsigned int i=0;i<keywordClasses.size();i++ )
+ {
+ sprintf ( styleName, "HL Keyword %c", 'A'+i ); //maybe better simple numbering
+ *out << getCharStyle ( KEYWORD+i, docStyle.getKeywordStyle ( keywordClasses[i] ), string ( styleName ) );
+ }
+ *out << "}}\n";
+ }
+
+ *out << "\\paperw"<< psMap[pageSize].width <<"\\paperh"<< psMap[pageSize].height
+ << "\\margl1134\\margr1134\\margt1134\\margb1134\\sectd" // page margins
+ << "\\plain\\f1\\fs" ; // Font formatting
+ int fontSize=0;
+ StringTools::str2num<int> ( fontSize, this->getBaseFontSize(), std::dec );
+ *out << ( ( fontSize ) ? fontSize*2: 20 ); // RTF needs double amount
+ *out << "\n\\pard \\cbpat1{";
+
+ processRootState();
+
+ *out << "}}"<<endl;
+ }
+
+ string RtfGenerator::getFooter()
+ {
+ return string();
+ }
+
+ void RtfGenerator::initOutputTags ( )
+ {
+ openTags.push_back ( getOpenTag ( STANDARD, docStyle.getDefaultStyle() ) );
+ openTags.push_back ( getOpenTag ( STRING, docStyle.getStringStyle() ) );
+ openTags.push_back ( getOpenTag ( NUMBER, docStyle.getNumberStyle() ) );
+ openTags.push_back ( getOpenTag ( SL_COMMENT, docStyle.getSingleLineCommentStyle() ) );
+ openTags.push_back ( getOpenTag ( ML_COMMENT,docStyle.getCommentStyle() ) );
+ openTags.push_back ( getOpenTag ( ESC_CHAR, docStyle.getEscapeCharStyle() ) );
+ openTags.push_back ( getOpenTag ( DIRECTIVE, docStyle.getDirectiveStyle() ) );
+ openTags.push_back ( getOpenTag ( DIRECTIVE_STRING, docStyle.getDirectiveStringStyle() ) );
+ openTags.push_back ( getOpenTag ( LINENUMBER, docStyle.getLineStyle() ) );
+ openTags.push_back ( getOpenTag ( SYMBOL, docStyle.getSymbolStyle() ) );
+
+ closeTags.push_back ( getCloseTag ( docStyle.getDefaultStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getStringStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getNumberStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getSingleLineCommentStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getCommentStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getEscapeCharStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getDirectiveStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getDirectiveStringStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getLineStyle() ) );
+ closeTags.push_back ( getCloseTag ( docStyle.getSymbolStyle() ) );
+ }
+
+ string RtfGenerator::maskCharacter ( unsigned char c )
+ {
+ switch ( c )
+ {
+ case '}' :
+ case '{' :
+ case '\\' :
+ {
+ string m ( "\\" );
+ return m += c;
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ string m ( 1, '{' );
+ m += c;
+ m += '}';
+ return m;
+ }
+ break;
+
+ case AUML_LC:
+ return "\\'e4";
+ break;
+ case OUML_LC:
+ return "\\'f6";
+ break;
+ case UUML_LC:
+ return "\\'fc";
+ break;
+ case AUML_UC:
+ return "\\'c4";
+ break;
+ case OUML_UC:
+ return "\\'d6";
+ break;
+ case UUML_UC:
+ return "\\'dc";
+ break;
+
+ case AACUTE_LC:
+ return "\\'e1";
+ break;
+ case EACUTE_LC:
+ return "\\'e9";
+ break;
+ case OACUTE_LC:
+ return "\\'f3";
+ break;
+ case UACUTE_LC:
+ return "\\'fa";
+ break;
+
+ case AGRAVE_LC:
+ return "\\'e0";
+ break;
+ case EGRAVE_LC:
+ return "\\'e8";
+ break;
+ case OGRAVE_LC:
+ return "\\'f2";
+ break;
+ case UGRAVE_LC:
+ return "\\'f9";
+ break;
+
+ case AACUTE_UC:
+ return "\\'c1";
+ break;
+ case EACUTE_UC:
+ return "\\'c9";
+ break;
+ case OACUTE_UC:
+ return "\\'d3";
+ break;
+ case UACUTE_UC:
+ return "\\'da";
+ break;
+ case AGRAVE_UC:
+ return "\\'c0";
+ break;
+ case EGRAVE_UC:
+ return "\\'c8";
+ break;
+ case OGRAVE_UC:
+ return "\\'d2";
+ break;
+ case UGRAVE_UC:
+ return "\\'d9";
+ break;
+
+ case SZLIG:
+ return "\\'df";
+ break;
+
+ default :
+ return string ( 1, c );
+ }
+ }
+
+ string RtfGenerator::getKeywordOpenTag ( unsigned int styleID )
+ {
+ return getOpenTag ( KEYWORD+styleID,
+ docStyle.getKeywordStyle ( langInfo.getKeywordClasses() [styleID] ) );
+ }
+
+ string RtfGenerator::getKeywordCloseTag ( unsigned int styleID )
+ {
+ return getCloseTag ( docStyle.getKeywordStyle ( langInfo.getKeywordClasses() [styleID] ) );
+ }
+
+ void RtfGenerator::setRTFPageSize ( const string & ps )
+ {
+ if ( psMap.count ( ps ) ) pageSize = ps;
+ }
+
+ void RtfGenerator::setRTFCharStyles ( bool cs )
+ {
+ addCharStyles = cs;
+ }
+
+}
diff --git a/support/highlight/src/core/rtfgenerator.h b/support/highlight/src/core/rtfgenerator.h
new file mode 100644
index 0000000000..e3d0ca614c
--- /dev/null
+++ b/support/highlight/src/core/rtfgenerator.h
@@ -0,0 +1,146 @@
+/***************************************************************************
+ rtfcode.h - description
+ -------------------
+ begin : Die Jul 9 2002
+ copyright : (C) 2002-2008 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef RTFGENERATOR_H
+#define RTFGENERATOR_H
+
+#include <string>
+
+#include "codegenerator.h"
+
+namespace highlight
+{
+
+ /**
+ PageSize contains the RTF page dimensions.
+ */
+ struct PageSize
+ {
+ /// RTF page width
+ int width;
+ /// RTF page height
+ int height;
+
+ PageSize()
+ {
+ }
+
+ /** Constructor to define page dimensions
+ @param w width
+ @param h height*/
+ PageSize ( int w, int h )
+ {
+ width=w;
+ height = h;
+ }
+
+ };
+
+ /** mapping of page size names and dimensions */
+ typedef map<string, struct PageSize> PagesizeMap;
+
+ /**
+ \brief This class generates RTF.
+
+ It contains information about the resulting document structure (document
+ header and footer), the colour system, white space handling and text
+ formatting attributes.
+
+ * @author Andre Simon
+ */
+
+ class RtfGenerator : public highlight::CodeGenerator
+ {
+ public:
+
+ RtfGenerator();
+
+ ~RtfGenerator();
+
+ /** Define RTF page size
+ \param ps RTF page size (a3, a4, a5, b4, b5, b6, letter, legal) */
+ void setRTFPageSize ( const string & ps );
+
+ /** \param cs flag to enable character styles*/
+ void setRTFCharStyles ( bool cs );
+
+ private:
+
+ /** prints document header
+ */
+ string getHeader();
+
+ /** Prints document footer*/
+ string getFooter();
+
+ /** Prints document body*/
+ void printBody();
+
+ /** initialize tags in specific format according to colouring information provided in DucumentStyle */
+ void initOutputTags();
+
+ /** Map of several pagesizes */
+ PagesizeMap psMap;
+
+ /** name of page size which is mapped to page dimensions*/
+ string pageSize;
+
+ /** flag to add character styles */
+ bool addCharStyles;
+
+ /** \return escaped character*/
+ virtual string maskCharacter ( unsigned char );
+
+ /**\return text formatting attributes in RTF format */
+ string getAttributes ( const ElementStyle & col );
+
+ /** @param styleNumber number of current style
+ @param elem associated element style
+ @return RTF formatting seqence (colour index + bold + italic)*/
+ string getOpenTag ( int styleNumber,const ElementStyle &elem );
+
+ /** @param styleNumber number of current style
+ @param elem associated element style
+ @param styleName style name
+ @return RTF character style definition */
+ string getCharStyle ( int styleNumber,const ElementStyle &elem, const string&styleName );
+
+ /** @param elem associated element style
+ @return RTF formatting sequnce to close element formatting */
+ string getCloseTag ( const ElementStyle &elem );
+
+ /** @param styleID current style ID
+ @return matching sequence to begin a new element formatting*/
+ string getKeywordOpenTag ( unsigned int styleID );
+
+ /** @param styleID current style ID
+ @return matching sequence to stop element formatting*/
+ string getKeywordCloseTag ( unsigned int styleID );
+ };
+
+}
+#endif
diff --git a/support/highlight/src/core/stringtools.cpp b/support/highlight/src/core/stringtools.cpp
new file mode 100644
index 0000000000..6db9df9900
--- /dev/null
+++ b/support/highlight/src/core/stringtools.cpp
@@ -0,0 +1,111 @@
+/***************************************************************************
+ stringtools.cpp - description
+ -------------------
+ begin : Mon Dec 10 2001
+ copyright : (C) 2001 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "stringtools.h"
+
+// Avoid problems with isspace and UTF-8 characters, use iswspace
+//#include <wctype.h>
+
+
+using namespace std;
+
+namespace StringTools
+{
+
+ string change_case ( const string & s, const KeywordCase kcase ) throw()
+ {
+ string r ( s );
+ switch ( kcase )
+ {
+ case CASE_UNCHANGED:
+ break;
+ case CASE_CAPITALIZE:
+ case CASE_LOWER:
+ for ( unsigned int i = 0; i < r.size(); ++i )
+ r[i] = tolower ( r[i] );
+ if ( kcase == CASE_CAPITALIZE && r.size() )
+ r[0] = toupper ( r[0] );
+ break;
+ case CASE_UPPER:
+ for ( unsigned int i = 0; i < r.size(); ++i )
+ r[i] = toupper ( r[i] );
+ break;
+ }
+ return r;
+ }
+
+
+ string trimRight ( const string &value )
+ {
+ string::size_type where = value.find_last_not_of ( " \t\r" );
+
+ if ( where == string::npos )
+ // string has nothing but space
+ return string();
+
+ if ( where == ( value.length() - 1 ) )
+ // string has no trailing space, don't copy its contents
+ return value;
+
+ return value.substr ( 0, where + 1 );
+ }
+
+ string getParantheseVal ( const string &s )
+ {
+ string::size_type openPos=s.find ( '(' );
+ string::size_type closePos=s.rfind ( ')' );
+ if ( openPos ==string::npos || closePos==string::npos )
+ {
+ return string();
+ }
+ return s.substr ( openPos+1, closePos-openPos-1 );
+ }
+
+ vector<string> splitString ( const string& s, unsigned char delim )
+ {
+ string::size_type pos=s.find ( delim ), oldPos=0;
+ vector <string> results;
+
+ if ( pos ==string::npos )
+ {
+ if ( !s.empty() ) results.push_back ( s );
+ return results;
+ }
+
+ do
+ {
+ if ( oldPos-pos ) results.push_back ( s.substr ( oldPos, pos-oldPos ) );
+ oldPos=pos+1;
+ pos=s.find ( delim, pos+1 );
+ }
+ while ( pos!=string::npos );
+ results.push_back ( s.substr ( oldPos ) );
+
+ return results;
+ }
+
+}
diff --git a/support/highlight/src/core/stringtools.h b/support/highlight/src/core/stringtools.h
new file mode 100644
index 0000000000..861ae85822
--- /dev/null
+++ b/support/highlight/src/core/stringtools.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ stringtools.h - description
+ -------------------
+ begin : Mon Dec 10 2001
+ copyright : (C) 2001 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef STRINGTOOLS_H
+#define STRINGTOOLS_H
+
+#include <string>
+#include <vector>
+#include <sstream>
+
+using namespace std;
+
+/// Contains methods for string manipulation
+
+namespace StringTools
+{
+
+ /** Change Keyword case */
+ enum KeywordCase
+ {
+ CASE_UNCHANGED, ///< do not alter case
+ CASE_LOWER, ///< convert to lower case
+ CASE_UPPER, ///< convert to upper case
+ CASE_CAPITALIZE ///< convert first character to upper case
+ };
+
+ /** Change character case of strings
+ \param s input string
+ \param kcase case modification indicator
+ \return modified string
+ */
+ string change_case ( const string & s,
+ const KeywordCase kcase = CASE_LOWER ) throw();
+
+ /** Trim string (remove whitespace)
+ \param value String
+ \return string trimmed on the left
+ */
+ string trimRight ( const string &value );
+
+ /** Parse data within parantheses
+ \param s String, containing a opening and a closing paranthesis
+ \return value between "(", ")" */
+ string getParantheseVal ( const string &s );
+
+ /** Split string and return items separated by a delimiter
+ \param s string containing tokens
+ \param delim Token delimiter
+ \return vector containing found tokens */
+ vector <string> splitString ( const string& s, unsigned char delim );
+
+ /** Convert string to a numeric value of the given type
+ \param val variable of specified type which will contain the numeric value
+ \param s string containing a number
+ \param f format specifier function (IO manipulator)
+ \return true if successfull */
+ template <class T>
+ bool str2num ( T &val, const std::string& s, std::ios_base& ( *f ) ( std::ios_base& ) )
+ {
+ std::istringstream iss ( s );
+ return ! ( iss >> f >> val ).fail();
+ }
+
+}
+
+#endif
diff --git a/support/highlight/src/core/stylecolour.cpp b/support/highlight/src/core/stylecolour.cpp
new file mode 100644
index 0000000000..3cfec3d743
--- /dev/null
+++ b/support/highlight/src/core/stylecolour.cpp
@@ -0,0 +1,157 @@
+/***************************************************************************
+ stylecolour.cpp - description
+ -------------------
+ begin : Die Nov 5 2002
+ copyright : (C) 2002 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "stylecolour.h"
+#include "stringtools.h"
+
+
+#include <iostream>
+#include <sstream>
+#include <cmath>
+
+using std::string;
+
+namespace highlight
+{
+
+ Colour::Colour ( const string & red, const string & green, const string & blue )
+ {
+ ostringstream rgbStream;
+ rgbStream << red << " " << green << " " << blue;
+ setRGB ( rgbStream.str() );
+ }
+
+ Colour::Colour()
+ {
+ rgb.iRed = rgb.iGreen = rgb.iBlue = 0;
+ }
+
+ Colour::Colour ( const string & colourString )
+ {
+ setRGB ( colourString );
+ }
+
+ void Colour::setRGB ( const string & colourString )
+ {
+ if ( colourString.empty() ) return;
+
+ istringstream valueStream ( colourString.c_str() );
+ string r, g, b;
+ char c='\0';
+ valueStream >> c;
+
+ if ( c=='#' )
+ {
+ string htmlNotation;
+ valueStream >> htmlNotation;
+ if ( htmlNotation.size() < 6 ) return;
+ r = htmlNotation.substr ( 0, 2 );
+ g = htmlNotation.substr ( 2, 2 );
+ b = htmlNotation.substr ( 4, 2 );
+ }
+ else
+ {
+ valueStream.putback ( c );
+ valueStream >> r;
+ valueStream >> g;
+ valueStream >> b;
+ }
+
+ StringTools::str2num<int> ( rgb.iRed, r, std::hex );
+ StringTools::str2num<int> ( rgb.iGreen, g, std::hex );
+ StringTools::str2num<int> ( rgb.iBlue, b, std::hex );
+ }
+
+ void Colour::setRed ( const string & red )
+ {
+ StringTools::str2num<int> ( rgb.iRed, red, std::hex );
+ }
+
+ void Colour::setGreen ( const string & green )
+ {
+ StringTools::str2num<int> ( rgb.iGreen, green, std::hex );
+ }
+
+ void Colour::setBlue ( const string & blue )
+ {
+ StringTools::str2num<int> ( rgb.iBlue, blue, std::hex );
+ }
+
+ string Colour::getRed ( OutputType type ) const
+ {
+ switch ( type )
+ {
+ case RTF: return int2str ( rgb.iRed, std::dec );
+ case LATEX: return float2str ( ( float ) rgb.iRed / 255 );
+ case TEX: return float2str ( 1 - ( float ) rgb.iRed / 255 );
+ default: return int2str ( rgb.iRed, std::hex );
+ }
+ }
+
+ string Colour::getGreen ( OutputType type ) const
+ {
+ switch ( type )
+ {
+ case RTF: return int2str ( rgb.iGreen, std::dec );
+ case LATEX: return float2str ( ( float ) rgb.iGreen / 255 );
+ case TEX: return float2str ( 1 - ( float ) rgb.iGreen / 255 );
+ default: return int2str ( rgb.iGreen, std::hex );
+ }
+ }
+
+ string Colour::getBlue ( OutputType type ) const
+ {
+ switch ( type )
+ {
+ case RTF: return int2str ( rgb.iBlue, std::dec );
+ case LATEX: return float2str ( ( float ) rgb.iBlue / 255 );
+ case TEX: return float2str ( 1 - ( float ) rgb.iBlue / 255 );
+ default: return int2str ( rgb.iBlue, std::hex );
+ }
+ }
+
+
+ string Colour::int2str ( const int num, std::ios_base& ( *f ) ( std::ios_base& ) ) const
+ {
+ std::ostringstream outStream;
+ outStream.width ( 2 );
+ outStream.fill ( '0' );
+ outStream << f << num;
+
+ return outStream.str();
+ }
+
+ string Colour::float2str ( const double num ) const
+ {
+ std::ostringstream outStream;
+ outStream << ( floor ( num * 100 + .5 ) / 100 );
+
+ return outStream.str();
+ }
+
+}
+
diff --git a/support/highlight/src/core/stylecolour.h b/support/highlight/src/core/stylecolour.h
new file mode 100644
index 0000000000..943952d6c2
--- /dev/null
+++ b/support/highlight/src/core/stylecolour.h
@@ -0,0 +1,106 @@
+/***************************************************************************
+ stylecolour.h - description
+ -------------------
+ begin : Die Nov 5 2002
+ copyright : (C) 2002 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef STYLECOLOUR_H
+#define STYLECOLOUR_H
+
+#include "enums.h"
+
+#include <string>
+
+
+using namespace std;
+
+namespace highlight
+{
+
+ /**\brief Stores colours and returns red, green and blue values in different formats
+ * @author Andre Simon
+ */
+
+ struct RGBVal
+ {
+ int iRed, ///< Red value
+ iGreen, ///< Green value
+ iBlue; ///< Blue value
+ };
+
+ class Colour
+ {
+ public:
+ /** Constructor
+ \param red Red value in hex notation
+ \param green Blue value in hex notation
+ \param blue Green value in hex notation
+ */
+ Colour ( const string & red, const string & green, const string & blue );
+
+ /** Constructor
+ \param ColourString String with rgb values
+ */
+ Colour ( const string & colourString );
+
+ Colour();
+ ~Colour() {};
+
+ /** Sets red, green and blue values
+ \param ColourString String containing colour attributes
+ */
+ void setRGB ( const string & colourString );
+
+
+ /** Sets red value
+ \param red New red value */
+ void setRed ( const string & red );
+
+ /** Sets green value
+ \param green New green value */
+ void setGreen ( const string & green );
+
+ /** Sets blue value
+ \param blue New blue value */
+ void setBlue ( const string & blue );
+
+ /** @param type Output type
+ @return Red value in color representation according to output type */
+ string getRed ( OutputType type ) const;
+ /** @param type Output type
+ @return Green value in color representation according to output type */
+ string getGreen ( OutputType type ) const;
+ /** @param type Output type
+ @return Blue value in color representation according to output type */
+ string getBlue ( OutputType type ) const;
+
+ private:
+ RGBVal rgb;
+ string int2str ( int, std::ios_base& ( *f ) ( std::ios_base& ) ) const;
+ string float2str ( double ) const;
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/svggenerator.cpp b/support/highlight/src/core/svggenerator.cpp
new file mode 100644
index 0000000000..10e41f6c07
--- /dev/null
+++ b/support/highlight/src/core/svggenerator.cpp
@@ -0,0 +1,248 @@
+/***************************************************************************
+ xmlcode.cpp - description
+ -------------------
+ begin : Mo 23.06.2008
+ copyright : (C) 2008 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <string>
+#include <sstream>
+
+#include "version.h"
+#include "svggenerator.h"
+
+using namespace std;
+namespace highlight
+{
+
+ SVGGenerator::SVGGenerator()
+ : CodeGenerator ( SVG )
+ {
+ spacer = " ";
+ newLineTag = "\n";
+ styleCommentOpen="/*";
+ styleCommentClose="*/";
+ }
+
+ SVGGenerator::~SVGGenerator() {}
+
+ void SVGGenerator::initOutputTags(){
+ openTags.push_back ( "" );
+ openTags.push_back ( getOpenTag ( STY_NAME_STR ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_NUM ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_SLC ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_COM ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_ESC ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_DIR ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_DST ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_LIN ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_SYM ) );
+
+ closeTags.push_back ( "" );
+ for ( int i=1;i<NUMBER_BUILTIN_STATES; i++ )
+ {
+ closeTags.push_back ( "</tspan>" );
+ }
+ }
+
+ string SVGGenerator::getStyleDefinition()
+ {
+ if ( styleDefinitionCache.empty() )
+ {
+ ostringstream os;
+ if ( includeStyleDef )
+ {
+ os << "<style type=\"text/css\">\n"
+ << "<![CDATA[\n";
+ }
+ os << "rect { fill:#"
+ << ( docStyle.getBgColour().getRed ( XML ) )
+ << ( docStyle.getBgColour().getGreen ( XML ) )
+ << ( docStyle.getBgColour().getBlue ( XML ) )
+ << "; } \n";
+ os << "g { font-size: " << getBaseFontSize();
+ os << "; font-family: \"" << getBaseFont() << "\"; }\n";
+ os << getAttributes ( "text", docStyle.getDefaultStyle() )
+ << getAttributes ( "tspan."+STY_NAME_NUM, docStyle.getNumberStyle() )
+ << getAttributes ( "tspan."+STY_NAME_ESC, docStyle.getEscapeCharStyle() )
+ << getAttributes ( "tspan."+STY_NAME_STR, docStyle.getStringStyle() )
+ << getAttributes ( "tspan."+STY_NAME_DST, docStyle.getDirectiveStringStyle() )
+ << getAttributes ( "tspan."+STY_NAME_SLC, docStyle.getSingleLineCommentStyle() )
+ << getAttributes ( "tspan."+STY_NAME_COM, docStyle.getCommentStyle() )
+ << getAttributes ( "tspan."+STY_NAME_DIR, docStyle.getDirectiveStyle() )
+ << getAttributes ( "tspan."+STY_NAME_SYM, docStyle.getSymbolStyle() )
+ << getAttributes ( "tspan."+STY_NAME_LIN, docStyle.getLineStyle() );
+
+ KeywordStyles styles = docStyle.getKeywordStyles();
+ for ( KSIterator it=styles.begin(); it!=styles.end(); it++ )
+ {
+ os << getAttributes ( "tspan."+it->first, it->second );
+ }
+ if ( includeStyleDef )
+ {
+ os << "]]>\n"
+ << "</style>";
+ }
+ styleDefinitionCache=os.str();
+ }
+ return styleDefinitionCache;
+ }
+
+
+ string SVGGenerator::getAttributes ( const string & elemName,
+ const ElementStyle & elem )
+ {
+ ostringstream s;
+ if ( !elemName.empty() )
+ {
+ s << /*cssClassName<<"."<<*/ elemName<<" { ";
+ }
+ s << "fill:#"
+ << ( elem.getColour().getRed ( HTML ) )
+ << ( elem.getColour().getGreen ( HTML ) )
+ << ( elem.getColour().getBlue ( HTML ) )
+ << ( elem.isBold() ? "; font-weight:bold" :"" )
+ << ( elem.isItalic() ? "; font-style:italic" :"" )
+ << ( elem.isUnderline() ? "; text-decoration:underline" :"" );
+ if ( !elemName.empty() )
+ {
+ s << "; }\n" ;
+ }
+ return s.str();
+ }
+
+ string SVGGenerator::getOpenTag ( const string& styleName )
+ {
+ return "<tspan class=\""+styleName+"\">";
+ }
+
+ string SVGGenerator::getHeader()
+ {
+ ostringstream header;
+ header << "<?xml version=\"1.0\"";
+ if ( encodingDefined() )
+ {
+ header << " encoding=\"" << encoding << "\"";
+ }
+ header << "?>\n";
+ if ( !includeStyleDef )
+ {
+ header << "<?xml-stylesheet type=\"text/css\" href=\""
+ << getStyleOutputPath()
+ << "\"?>\n";
+ }
+ header << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.2//EN\" "
+ << "\"http://www.w3.org/Graphics/SVG/1.2/DTD/svg12.dtd\">\n";
+ header << "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.2\" "
+ << "baseProfile=\"full\" xml:space=\"preserve\"";
+ if ( width.size() ) header << " width=\""<<width<<"\"";
+ if ( height.size() ) header << " height=\""<<height<<"\"";
+ //viewBox=\"0 0 800 600\"
+ header << ">\n<desc>" << docTitle << "</desc>\n";
+ if ( includeStyleDef )
+ {
+ header << "<defs>\n";
+ header << getStyleDefinition();
+ header << "\n</defs>\n";
+ }
+ return header.str();
+ }
+
+ void SVGGenerator::printBody()
+ {
+ *out << "<g>\n<rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\"/>"; // rect: background color
+ int fontSize=0;
+ StringTools::str2num<int> ( fontSize, getBaseFontSize(), std::dec );
+ *out << "\n<text x=\"10\" y=\""<<fontSize*2<<"\">";
+ processRootState();
+ *out << "</text>\n</g>\n";
+ }
+
+
+ string SVGGenerator::getFooter()
+ {
+ ostringstream os;
+ os <<"</svg>\n";
+ os<< "<!-- SVG generated by Highlight "
+ << HIGHLIGHT_VERSION
+ << ", "
+ << HIGHLIGHT_URL
+ <<" -->\n";
+ return os.str();
+ }
+
+ string SVGGenerator::maskCharacter ( unsigned char c )
+ {
+ switch ( c )
+ {
+ case '<' :
+ return "&lt;";
+ break;
+ case '>' :
+ return "&gt;";
+ break;
+ case '&' :
+ return "&amp;";
+ break;
+ case '\"' :
+ return "&quot;";
+ break;
+ default:
+ return string ( 1, c );
+ }
+ }
+
+ string SVGGenerator::getKeywordOpenTag ( unsigned int styleID )
+ {
+ return getOpenTag ( langInfo.getKeywordClasses() [styleID] );
+ }
+
+ string SVGGenerator::getKeywordCloseTag ( unsigned int styleID )
+ {
+ return "</tspan>";
+ }
+
+ string SVGGenerator::getNewLine()
+ {
+
+ if ( lineNumber>1 )
+ {
+ ostringstream os;
+ int fontSize=0;
+ StringTools::str2num<int> ( fontSize, getBaseFontSize(), std::dec );
+ os<< "</text>\n<text x=\"10\" y=\""<< ( lineNumber*fontSize*2 ) <<"\">";
+ return os.str();
+ }
+ else
+ {
+ return "";
+ }
+ }
+
+ void SVGGenerator::setSVGSize ( const string& w, const string& h )
+ {
+ width=w;
+ height=h;
+ }
+
+}
diff --git a/support/highlight/src/core/svggenerator.h b/support/highlight/src/core/svggenerator.h
new file mode 100644
index 0000000000..35b8afe57d
--- /dev/null
+++ b/support/highlight/src/core/svggenerator.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ xmlcode.h - description
+ -------------------
+ begin : Mo 23.06.2008
+ copyright : (C) 2008 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef SVGGenerator_H
+#define SVGGenerator_H
+
+#include "codegenerator.h"
+
+namespace highlight
+{
+
+ /**
+ \brief This class generates SVG.
+
+ It contains information about the resulting document structure (document
+ header and footer), the colour system, white space handling and text
+ formatting attributes.
+
+ * @author Andre Simon
+ */
+
+ class SVGGenerator : public highlight::CodeGenerator
+ {
+ public:
+
+ SVGGenerator();
+ ~SVGGenerator();
+
+ /** Set SVG dimensions
+ \param w page width
+ \param h page height
+ */
+ void setSVGSize ( const string& w, const string& h );
+
+ private:
+
+ /** prints document header
+ */
+ string getHeader();
+
+ /** Prints document footer*/
+ string getFooter();
+
+ /** Prints document body*/
+ void printBody();
+
+ /** initialize tags in specific format according to colouring information provided in DucumentStyle */
+ void initOutputTags();
+
+ string styleDefinitionCache;
+ string width, height;
+
+ string getStyleDefinition();
+
+ string getAttributes ( const string &, const ElementStyle & );
+
+ /** \return escaped character*/
+ virtual string maskCharacter ( unsigned char );
+
+ string getOpenTag ( const string& );
+
+ string getKeywordOpenTag ( unsigned int styleID );
+ string getKeywordCloseTag ( unsigned int styleID );
+
+ /** @return Newline string */
+ string getNewLine();
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/texgenerator.cpp b/support/highlight/src/core/texgenerator.cpp
new file mode 100644
index 0000000000..276af5a7c6
--- /dev/null
+++ b/support/highlight/src/core/texgenerator.cpp
@@ -0,0 +1,303 @@
+/***************************************************************************
+ TexGenerator.cpp - description
+ -------------------
+ begin : Mit Jul 24 2002
+ copyright : (C) 2002 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <sstream>
+
+#include "charcodes.h"
+#include "version.h"
+#include "texgenerator.h"
+
+namespace highlight
+{
+
+ TexGenerator::TexGenerator()
+ : CodeGenerator ( TEX )
+ {
+
+
+ /*This makes TeX to use every par it encounters (the \\leavevmode has
+ no effect when TeX is in horizontal mode and when TeX is in vertical
+ mode, it switches it to horizontal mode).*/
+ newLineTag="\\leavevmode\\par\n";
+
+ spacer = "\\ ";
+ maskWs=true;
+ excludeWs=true;
+ maskWsBegin = "{\\hlstd";
+ maskWsEnd = "}";
+ styleCommentOpen="%";
+ }
+
+ TexGenerator::~TexGenerator()
+ {}
+
+ void TexGenerator::initOutputTags(){
+ openTags.push_back ( "{\\hl"+STY_NAME_STD+" " );
+ openTags.push_back ( "{\\hl"+STY_NAME_STR+" " );
+ openTags.push_back ( "{\\hl"+STY_NAME_NUM+" " );
+ openTags.push_back ( "{\\hl"+STY_NAME_SLC+" " );
+ openTags.push_back ( "{\\hl"+STY_NAME_COM+" " );
+ openTags.push_back ( "{\\hl"+STY_NAME_ESC+" " );
+ openTags.push_back ( "{\\hl"+STY_NAME_DIR+" " );
+ openTags.push_back ( "{\\hl"+STY_NAME_DST+" " );
+ openTags.push_back ( "{\\hl"+STY_NAME_LIN+" " );
+ openTags.push_back ( "{\\hl"+STY_NAME_SYM+" " );
+
+ for ( int i=0; i<NUMBER_BUILTIN_STATES; i++ )
+ {
+ closeTags.push_back ( "}" );
+ }
+ }
+
+ string TexGenerator::getAttributes ( const string & elemName,const ElementStyle & elem )
+ {
+ ostringstream s;
+ s << "\\def\\hl"
+ << elemName
+ << "{";
+ if ( elem.isBold() ) s << "\\bf";
+ if ( elem.isItalic() ) s << "\\it";
+ s << "\\textColor{"
+ << ( elem.getColour().getRed ( TEX ) ) <<" "
+ << ( elem.getColour().getGreen ( TEX ) ) <<" "
+ << ( elem.getColour().getBlue ( TEX ) ) <<" 0.0}}\n";
+ return s.str();
+ }
+
+ string TexGenerator::getHeader()
+ {
+ ostringstream os;
+ os << styleCommentOpen
+ << " Document title: " << docTitle << "\n\n";
+ if ( langInfo.highlightingEnabled() )
+ {
+ if ( includeStyleDef )
+ {
+ os << getStyleDefinition();
+ os << CodeGenerator::readUserStyleDef();
+ }
+ else
+ {
+ os << "\\input "
+ << getStyleOutputPath()
+ << "\n\n";
+ }
+ }
+
+ return os.str();
+ }
+
+ void TexGenerator::printBody()
+ {
+ *out << "{\n\\"<<getBaseFont() <<"\n";
+
+ processRootState();
+
+ *out << "}\n";
+ }
+
+ string TexGenerator::getFooter()
+ {
+ ostringstream os;
+ os << "\\bye\n"
+ << "% TeX generated by Highlight "
+ << HIGHLIGHT_VERSION
+ << ", "
+ << HIGHLIGHT_URL
+ << endl;
+ return os.str();
+ }
+
+ string TexGenerator:: maskCharacter ( unsigned char c )
+ {
+ switch ( c )
+ {
+ case '{':
+ case '}':
+ {
+ string m ( "$\\" );
+ m += c;
+ m += '$';
+ return m;
+ }
+ break;
+ case '^':
+ return "{\\bf\\^{}}";
+ break;
+ case '_':
+ return "\\_{}";
+ break;
+ case '&':
+ case '$':
+ case '#':
+ case '%':
+ {
+ string m ( "\\" );
+ m += c;
+ return m;
+ }
+ break;
+ case '\\':
+ return "$\\backslash$";
+ break;
+ case ' ':
+ return spacer;
+ break;
+ case '+':
+ case '-':
+ case '<':
+ case '>':
+ case '=':
+ {
+ string m ( "$\\mathord{" );
+ m += c;
+ m += "}$";
+ return m;
+ }
+ break;
+ case AUML_LC:
+ return "\\\"a";
+ break;
+ case OUML_LC:
+ return "\\\"o";
+ break;
+ case UUML_LC:
+ return "\\\"u";
+ break;
+ case AUML_UC:
+ return "\\\"A";
+ break;
+ case OUML_UC:
+ return "\\\"O";
+ break;
+ case UUML_UC:
+ return "\\\"U";
+ break;
+ case AACUTE_LC:
+ return "\\'a";
+ break;
+ case EACUTE_LC:
+ return "\\'e";
+ break;
+ case OACUTE_LC:
+ return "\\'o";
+ break;
+ case UACUTE_LC:
+ return "\\'u";
+ break;
+ case AGRAVE_LC:
+ return "\\`a";
+ break;
+ case EGRAVE_LC:
+ return "\\`e";
+ break;
+ case OGRAVE_LC:
+ return "\\`o";
+ break;
+ case UGRAVE_LC:
+ return "\\`u";
+ break;
+ case AACUTE_UC:
+ return "\\'A";
+ break;
+ case EACUTE_UC:
+ return "\\'E";
+ break;
+ case OACUTE_UC:
+ return "\\'O";
+ break;
+ case UACUTE_UC:
+ return "\\'U";
+ break;
+ case AGRAVE_UC:
+ return "\\`A";
+ break;
+ case EGRAVE_UC:
+ return "\\`E";
+ break;
+ case UGRAVE_UC:
+ return "\\`O";
+ break;
+ case OGRAVE_UC:
+ return "\\`U";
+ break;
+ case SZLIG:
+ return "\\ss ";
+ break;
+
+ default :
+ return string ( 1, c );
+ }
+ }
+
+ string TexGenerator::getKeywordOpenTag ( unsigned int styleID )
+ {
+ return "{\\hl"+langInfo.getKeywordClasses() [styleID]+" ";
+ }
+
+ string TexGenerator::getKeywordCloseTag ( unsigned int styleID )
+ {
+ return "}";
+ }
+
+
+ string TexGenerator::getStyleDefinition()
+ {
+ if ( styleDefinitionCache.empty() )
+ {
+ ostringstream os;
+ os << getAttributes ( STY_NAME_STD, docStyle.getDefaultStyle() );
+ os << getAttributes ( STY_NAME_NUM, docStyle.getNumberStyle() );
+ os << getAttributes ( STY_NAME_ESC, docStyle.getEscapeCharStyle() );
+ os << getAttributes ( STY_NAME_STR, docStyle.getStringStyle() );
+ os << getAttributes ( STY_NAME_DST, docStyle.getDirectiveStringStyle() );
+ os << getAttributes ( STY_NAME_SLC, docStyle.getSingleLineCommentStyle() );
+ os << getAttributes ( STY_NAME_COM, docStyle.getCommentStyle() );
+ os << getAttributes ( STY_NAME_DIR, docStyle.getDirectiveStyle() );
+ os << getAttributes ( STY_NAME_LIN, docStyle.getLineStyle() );
+ os << getAttributes ( STY_NAME_SYM, docStyle.getSymbolStyle() );
+
+ KeywordStyles styles = docStyle.getKeywordStyles();
+ for ( KSIterator it=styles.begin(); it!=styles.end(); it++ )
+ {
+ os << getAttributes ( it->first, it->second );
+ }
+
+ os << "% The special option is not supported by all dvi drivers\n"
+ << "\\special{background rgb "
+ << docStyle.getBgColour().getRed ( LATEX ) << " "
+ << docStyle.getBgColour().getGreen ( LATEX ) << " "
+ << docStyle.getBgColour().getBlue ( LATEX ) << "}";
+ os << "\n\\nopagenumbers\n"
+ << "\\input colordvi\n";
+ styleDefinitionCache=os.str();
+ }
+ return styleDefinitionCache;
+ }
+
+
+}
diff --git a/support/highlight/src/core/texgenerator.h b/support/highlight/src/core/texgenerator.h
new file mode 100644
index 0000000000..becd31cd57
--- /dev/null
+++ b/support/highlight/src/core/texgenerator.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+ texcode.h - description
+ -------------------
+ begin : Mit Jul 24 2002
+ copyright : (C) 2002 by Andr�Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef TEXGENERATOR_H
+#define TEXGENERATOR_H
+
+#include <string>
+
+#include "codegenerator.h"
+
+
+namespace highlight
+{
+
+ /**
+ \brief This class generates TeX.
+
+ It contains information about the resulting document structure (document
+ header and footer), the colour system, white space handling and text
+ formatting attributes.
+
+ * @author Andre Simon
+ */
+
+ class TexGenerator : public highlight::CodeGenerator
+ {
+ public:
+
+ TexGenerator();
+ ~TexGenerator();
+
+ private:
+
+ /** prints document header
+ */
+ string getHeader();
+
+ /** Prints document footer*/
+ string getFooter();
+
+ /** Prints document body*/
+ void printBody();
+
+ /** initialize tags in specific format according to colouring information provided in DucumentStyle */
+ void initOutputTags();
+
+ string styleDefinitionCache;
+
+ string getStyleDefinition();
+
+ /** \return escaped character*/
+ virtual string maskCharacter ( unsigned char );
+
+ /**\return text formatting attributes in RTF format */
+ string getAttributes ( const string & elemName, const ElementStyle & elem );
+
+ /** @param styleID current style ID
+ @return matching sequence to begin a new element formatting*/
+ string getKeywordOpenTag ( unsigned int styleID );
+
+ /** @param styleID current style ID
+ @return matching sequence to stop element formatting*/
+ string getKeywordCloseTag ( unsigned int styleID );
+
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/version.h b/support/highlight/src/core/version.h
new file mode 100644
index 0000000000..a667705b9e
--- /dev/null
+++ b/support/highlight/src/core/version.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ version.h - description
+ -------------------
+ begin : Mon March 3 2003
+ copyright : (C) 2003-2010 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef VERSION_H
+#define VERSION_H
+
+#define HIGHLIGHT_VERSION "2.16"
+
+#define HIGHLIGHT_URL "http://www.andre-simon.de/"
+#define HIGHLIGHT_EMAIL "andre.simon1@gmx.de"
+
+#endif
diff --git a/support/highlight/src/core/xhtmlgenerator.cpp b/support/highlight/src/core/xhtmlgenerator.cpp
new file mode 100644
index 0000000000..aed05a2986
--- /dev/null
+++ b/support/highlight/src/core/xhtmlgenerator.cpp
@@ -0,0 +1,92 @@
+/***************************************************************************
+ htmlcode.cpp - description
+ -------------------
+ begin : Wed Nov 28 2001
+ copyright : (C) 2001 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "xhtmlgenerator.h"
+
+using namespace std;
+
+namespace highlight
+{
+
+ XHtmlGenerator::XHtmlGenerator ()
+ {
+ fileSuffix=".xhtml";
+ brTag="<br />";
+ hrTag="<hr />";
+ idAttr="id";
+ cssClassName="hl";
+ }
+
+ string XHtmlGenerator::getHeaderStart ( const string &title )
+ {
+ ostringstream header;
+ header << "<?xml version=\"1.0\"";
+ if ( encodingDefined() )
+ {
+ header << " encoding=\"" << encoding << "\"";
+ }
+ header << "?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\""
+ << " \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
+ << "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
+ << "<head>\n<title>" << title << "</title>\n";
+
+ return header.str();
+ }
+
+
+ string XHtmlGenerator::getHeader()
+ {
+ ostringstream os;
+ os << getHeaderStart ( docTitle );
+
+ if ( langInfo.highlightingEnabled() )
+ {
+ if ( includeStyleDef )
+ {
+ os << "<style type=\"text/css\">\n";
+ os << "<![CDATA[\n";
+ os << getStyleDefinition();
+ os << CodeGenerator::readUserStyleDef();
+ os << "]]>\n";
+ os << "</style>\n";
+ }
+ else
+ {
+ os << "<link rel=\"stylesheet\" type=\"text/css\" href=\""
+ << getStyleOutputPath()
+ << "\""
+ << "/"
+ << ">\n";
+ }
+ }
+ os << "</head>\n<body class=\""<<cssClassName<<"\">";
+ //if (showLineNumbers && orderedList) os << "<ol>";
+
+ return os.str();
+ }
+
+}
diff --git a/support/highlight/src/core/xhtmlgenerator.h b/support/highlight/src/core/xhtmlgenerator.h
new file mode 100644
index 0000000000..7efca1a636
--- /dev/null
+++ b/support/highlight/src/core/xhtmlgenerator.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ xhtmlgenerator.h - description
+ -------------------
+ begin : Mo Jun 21 2004
+ copyright : (C) 2004 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+
+#ifndef XHTMLGENERATOR_H
+#define XHTMLGENERATOR_H
+
+#include "htmlgenerator.h"
+
+namespace highlight
+{
+
+ /**
+ \brief This class generates XHTML.
+
+ It contains information about the resulting document structure (document
+ header and footer), the colour system, white space handling and text
+ formatting attributes.
+
+ * @author Andre Simon
+ */
+
+
+ class XHtmlGenerator : public highlight::HtmlGenerator
+ {
+ public:
+
+ XHtmlGenerator();
+
+ ~XHtmlGenerator() {};
+
+ private:
+
+ /** prints document header
+ */
+ string getHeader();
+
+ string getHeaderStart ( const string &title );
+
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/xmlgenerator.cpp b/support/highlight/src/core/xmlgenerator.cpp
new file mode 100644
index 0000000000..dd66dd2652
--- /dev/null
+++ b/support/highlight/src/core/xmlgenerator.cpp
@@ -0,0 +1,202 @@
+/***************************************************************************
+ xmlcode.cpp - description
+ -------------------
+ begin : Do 20.01.2005
+ copyright : (C) 2005 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <string>
+#include <sstream>
+
+#include "version.h"
+#include "xmlgenerator.h"
+
+using namespace std;
+namespace highlight
+{
+
+ XmlGenerator::XmlGenerator()
+ : CodeGenerator ( XML )
+ {
+ spacer = " ";
+ newLineTag = "<br />\n";
+ }
+
+ XmlGenerator::~XmlGenerator() {}
+
+ string XmlGenerator::getHeader()
+ {
+ ostringstream header;
+ header << "<?xml version=\"1.0\"";
+ if ( encodingDefined() )
+ {
+ header << " encoding=\"" << encoding << "\"";
+ }
+ header << "?>\n<document>";
+ header << "\n<title>" << docTitle << "</title>";
+ header << getStyleDefinition();
+ return header.str();
+ }
+
+ void XmlGenerator::printBody()
+ {
+ *out << "<source>\n";
+ processRootState();
+ *out << "</source>\n";
+ }
+
+
+ string XmlGenerator::getFooter()
+ {
+ ostringstream os;
+ os <<"</document>\n";
+ os<< "<!-- XML generated by Highlight "
+ << HIGHLIGHT_VERSION
+ << ", "
+ << HIGHLIGHT_URL
+ <<" -->\n";
+ return os.str();
+ }
+
+ void XmlGenerator::initOutputTags(){
+ openTags.push_back ( getOpenTag ( STY_NAME_STD ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_STR ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_NUM ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_SLC ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_COM ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_ESC ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_DIR ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_DST ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_LIN ) );
+ openTags.push_back ( getOpenTag ( STY_NAME_SYM ) );
+
+ closeTags.push_back ( getCloseTag ( STY_NAME_STD ) );
+ closeTags.push_back ( getCloseTag ( STY_NAME_STR ) );
+ closeTags.push_back ( getCloseTag ( STY_NAME_NUM ) );
+ closeTags.push_back ( getCloseTag ( STY_NAME_SLC ) );
+ closeTags.push_back ( getCloseTag ( STY_NAME_COM ) );
+ closeTags.push_back ( getCloseTag ( STY_NAME_ESC ) );
+ closeTags.push_back ( getCloseTag ( STY_NAME_DIR ) );
+ closeTags.push_back ( getCloseTag ( STY_NAME_DST ) );
+ closeTags.push_back ( getCloseTag ( STY_NAME_LIN ) );
+ closeTags.push_back ( getCloseTag ( STY_NAME_SYM ) );
+ }
+
+ string XmlGenerator::getStyleDefinition()
+ {
+ if ( styleDefinitionCache.empty() )
+ {
+ ostringstream os;
+ os << "\n<style>\n"
+ << "\t<bgcolor value=\""
+ << ( docStyle.getBgColour().getRed ( XML ) )
+ << ( docStyle.getBgColour().getGreen ( XML ) )
+ << ( docStyle.getBgColour().getBlue ( XML ) )
+ << "\" />\n";
+ os << "\t<font size=\"" << getBaseFontSize();
+ os << "\" family=\"" << getBaseFont() << "\" />\n";
+ os << getAttributes ( STY_NAME_STD, docStyle.getDefaultStyle() )
+ << getAttributes ( STY_NAME_NUM, docStyle.getNumberStyle() )
+ << getAttributes ( STY_NAME_ESC, docStyle.getEscapeCharStyle() )
+ << getAttributes ( STY_NAME_STR, docStyle.getStringStyle() )
+ << getAttributes ( STY_NAME_DST, docStyle.getDirectiveStringStyle() )
+ << getAttributes ( STY_NAME_SLC, docStyle.getSingleLineCommentStyle() )
+ << getAttributes ( STY_NAME_COM, docStyle.getCommentStyle() )
+ << getAttributes ( STY_NAME_DIR, docStyle.getDirectiveStyle() )
+ << getAttributes ( STY_NAME_SYM, docStyle.getSymbolStyle() )
+ << getAttributes ( STY_NAME_LIN, docStyle.getLineStyle() );
+
+ KeywordStyles styles = docStyle.getKeywordStyles();
+ for ( KSIterator it=styles.begin(); it!=styles.end(); it++ )
+ {
+ os << getAttributes ( it->first, it->second );
+ }
+ os << "</style>\n";
+ styleDefinitionCache=os.str();
+ }
+ return styleDefinitionCache;
+ }
+
+
+ string XmlGenerator::getAttributes ( const string & elemName,
+ const ElementStyle & elem )
+ {
+ ostringstream s;
+ s << "\t<class name=\""
+ << elemName
+ <<"\" color=\""
+ << ( elem.getColour().getRed ( XML ) )
+ << ( elem.getColour().getGreen ( XML ) )
+ << ( elem.getColour().getBlue ( XML ) )
+ << "\" bold=\""
+ << ( elem.isBold() ? "true" :"false" )
+ << "\" italic=\""
+ << ( elem.isItalic() ? "true" :"false" )
+ << "\" underline=\""
+ << ( elem.isUnderline() ? "true" :"false" )
+ << "\" />\n" ;
+ return s.str();
+ }
+
+ string XmlGenerator::getOpenTag ( const string& styleName )
+ {
+ return "<"+styleName+">";
+ }
+
+ string XmlGenerator::getCloseTag ( const string& styleName )
+ {
+ return "</"+styleName+">";
+ }
+
+ string XmlGenerator::maskCharacter ( unsigned char c )
+ {
+ switch ( c )
+ {
+ case '<' :
+ return "&lt;";
+ break;
+ case '>' :
+ return "&gt;";
+ break;
+ case '&' :
+ return "&amp;";
+ break;
+ case '\"' :
+ return "&quot;";
+ break;
+ default:
+ return string ( 1, c );
+ }
+ }
+
+ string XmlGenerator::getKeywordOpenTag ( unsigned int styleID )
+ {
+ return getOpenTag ( langInfo.getKeywordClasses() [styleID] );
+ }
+
+ string XmlGenerator::getKeywordCloseTag ( unsigned int styleID )
+ {
+ return getCloseTag ( langInfo.getKeywordClasses() [styleID] );
+ }
+
+}
diff --git a/support/highlight/src/core/xmlgenerator.h b/support/highlight/src/core/xmlgenerator.h
new file mode 100644
index 0000000000..74319fdec7
--- /dev/null
+++ b/support/highlight/src/core/xmlgenerator.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ xmlcode.h - description
+ -------------------
+ begin : Do 20.01.2005
+ copyright : (C) 2005 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef XMLGENERATOR_H
+#define XMLGENERATOR_H
+
+#include "codegenerator.h"
+
+namespace highlight
+{
+
+ /**
+ \brief This class generates XML.
+
+ It contains information about the resulting document structure (document
+ header and footer), the colour system, white space handling and text
+ formatting attributes.
+
+ * @author Andre Simon
+ */
+
+ class XmlGenerator : public highlight::CodeGenerator
+ {
+ public:
+
+ XmlGenerator();
+ ~XmlGenerator();
+
+ private:
+
+ /** prints document header
+ */
+ string getHeader();
+
+ /** Prints document footer*/
+ string getFooter();
+
+ /** Prints document body*/
+ void printBody();
+
+ /** initialize tags in specific format according to colouring information provided in DucumentStyle */
+ void initOutputTags();
+
+ string styleDefinitionCache;
+
+ string getStyleDefinition();
+
+ string getAttributes ( const string &, const ElementStyle & );
+
+ /** \return escaped character*/
+ virtual string maskCharacter ( unsigned char );
+
+ string getOpenTag ( const string& );
+ string getCloseTag ( const string& );
+
+ string getKeywordOpenTag ( unsigned int styleID );
+ string getKeywordCloseTag ( unsigned int styleID );
+ };
+
+}
+
+#endif
diff --git a/support/highlight/src/core/xterm256generator.cpp b/support/highlight/src/core/xterm256generator.cpp
new file mode 100644
index 0000000000..d351d19b8d
--- /dev/null
+++ b/support/highlight/src/core/xterm256generator.cpp
@@ -0,0 +1,208 @@
+/***************************************************************************
+ xterm256generator.cpp - description
+ -------------------
+ begin : Oct 13 2006
+ copyright : (C) 2006 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <sstream>
+
+#include "xterm256generator.h"
+#include "charcodes.h"
+#include "version.h"
+
+using namespace std;
+
+namespace highlight
+{
+ Xterm256Generator::Xterm256Generator() : CodeGenerator ( XTERM256 )
+ {
+
+ newLineTag = "\n";
+ spacer = " ";
+ }
+
+ Xterm256Generator::~Xterm256Generator() {}
+
+ string Xterm256Generator::getHeader()
+ {
+ return string();
+ }
+
+ void Xterm256Generator::printBody()
+ {
+ processRootState();
+ }
+
+ string Xterm256Generator::getFooter()
+ {
+ return string();
+ }
+
+ string Xterm256Generator::maskCharacter ( unsigned char c )
+ {
+ return string ( 1, c );
+ }
+
+ void Xterm256Generator::initOutputTags ( )
+ {
+ openTags.push_back ( getOpenTag ( docStyle.getDefaultStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getStringStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getNumberStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getSingleLineCommentStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getCommentStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getEscapeCharStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getDirectiveStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getDirectiveStringStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getLineStyle() ) );
+ openTags.push_back ( getOpenTag ( docStyle.getSymbolStyle() ) );
+
+ for ( int i=0;i<NUMBER_BUILTIN_STATES; i++ )
+ {
+ closeTags.push_back ( "\033[m" );
+ }
+ }
+
+ string Xterm256Generator::getOpenTag ( const ElementStyle &col )
+ {
+
+ Colour c= col.getColour();
+ unsigned char rgb[3];
+ rgb[0] = ( unsigned char ) strtoll ( c.getRed ( HTML ).c_str(), NULL, 16 );
+ rgb[1] = ( unsigned char ) strtoll ( c.getGreen ( HTML ).c_str(), NULL, 16 );
+ rgb[2] = ( unsigned char ) strtoll ( c.getBlue ( HTML ).c_str(), NULL, 16 );
+
+ ostringstream s;
+ s << "\033[38;5;"<< ( int ) rgb2xterm ( rgb ) << "m";
+ return s.str();
+ }
+
+ string Xterm256Generator::getKeywordOpenTag ( unsigned int styleID )
+ {
+ return getOpenTag ( docStyle.getKeywordStyle ( langInfo.getKeywordClasses() [styleID] ) );
+ }
+
+ string Xterm256Generator::getKeywordCloseTag ( unsigned int styleID )
+ {
+ return "\033[m";
+ }
+
+ /* the following functions are based on Wolfgang Frischs xterm256 converter utility:
+ http://frexx.de/xterm-256-notes/
+ */
+
+ void Xterm256Generator::xterm2rgb ( unsigned char color, unsigned char* rgb )
+ {
+ // 16 basic colors
+ if ( color<16 )
+ {
+ rgb[0] = basic16[color][0];
+ rgb[1] = basic16[color][1];
+ rgb[2] = basic16[color][2];
+ }
+
+ // color cube color
+ if ( color>=16 && color<=232 )
+ {
+ color-=16;
+ rgb[0] = valuerange[ ( color/36 ) %6];
+ rgb[1] = valuerange[ ( color/6 ) %6];
+ rgb[2] = valuerange[color%6];
+ }
+
+ // gray tone
+ if ( color>=233 && color<=253 )
+ {
+ rgb[0]=rgb[1]=rgb[2] = 8+ ( color-232 ) *0x0a;
+ }
+ }
+
+ void Xterm256Generator::maketable()
+ {
+ unsigned char c, rgb[3];
+ for ( c=0;c<=253;c++ )
+ {
+ xterm2rgb ( c,rgb );
+ colortable[c][0] = rgb[0];
+ colortable[c][1] = rgb[1];
+ colortable[c][2] = rgb[2];
+ }
+ }
+
+ unsigned char Xterm256Generator::rgb2xterm ( unsigned char* rgb )
+ {
+ unsigned char c, best_match=0;
+ double d, smallest_distance;
+
+ if ( !initialized )
+ {
+ maketable();
+ initialized = true;
+ }
+
+ smallest_distance = 10000000000.0;
+
+ for ( c=0;c<=253;c++ )
+ {
+ d = pow ( colortable[c][0]-rgb[0],2.0 ) +
+ pow ( colortable[c][1]-rgb[1],2.0 ) +
+ pow ( colortable[c][2]-rgb[2],2.0 );
+ if ( d<smallest_distance )
+ {
+ smallest_distance = d;
+ best_match=c;
+ }
+ }
+ return best_match;
+ }
+
+ bool Xterm256Generator::initialized=false;
+ unsigned char Xterm256Generator::colortable[254][3];
+
+ const unsigned char Xterm256Generator::valuerange[] = { 0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF };
+
+ const unsigned char Xterm256Generator::basic16[16][3] =
+ {
+ { 0x00, 0x00, 0x00 }, // 0
+ { 0xCD, 0x00, 0x00 }, // 1
+ { 0x00, 0xCD, 0x00 }, // 2
+ { 0xCD, 0xCD, 0x00 }, // 3
+ { 0x00, 0x00, 0xEE }, // 4
+ { 0xCD, 0x00, 0xCD }, // 5
+ { 0x00, 0xCD, 0xCD }, // 6
+ { 0xE5, 0xE5, 0xE5 }, // 7
+ { 0x7F, 0x7F, 0x7F }, // 8
+ { 0xFF, 0x00, 0x00 }, // 9
+ { 0x00, 0xFF, 0x00 }, // 10
+ { 0xFF, 0xFF, 0x00 }, // 11
+ { 0x5C, 0x5C, 0xFF }, // 12
+ { 0xFF, 0x00, 0xFF }, // 13
+ { 0x00, 0xFF, 0xFF }, // 14
+ { 0xFF, 0xFF, 0xFF } // 15
+ };
+
+
+}
diff --git a/support/highlight/src/core/xterm256generator.h b/support/highlight/src/core/xterm256generator.h
new file mode 100644
index 0000000000..e68b78c4c6
--- /dev/null
+++ b/support/highlight/src/core/xterm256generator.h
@@ -0,0 +1,111 @@
+/***************************************************************************
+ xterm256generator.h - description
+ -------------------
+ begin : Oct 13 2006
+ copyright : (C) 2006-2007 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef XTERM256GENERATOR_H
+#define XTERM256GENERATOR_H
+
+#include <string>
+
+#include "codegenerator.h"
+
+
+namespace highlight
+{
+
+ /**
+ \brief This class generates xterm 256 color escape sequences.
+
+ It contains information about the resulting document structure (document
+ header and footer), the colour system, white space handling and text
+ formatting attributes.
+
+ * @author Andre Simon
+ */
+
+ class Xterm256Generator : public highlight::CodeGenerator
+ {
+ public:
+ Xterm256Generator();
+ ~Xterm256Generator();
+
+ private:
+
+ /** prints document header
+ */
+ string getHeader();
+
+ /** Prints document footer*/
+ string getFooter();
+
+ /** Prints document body*/
+ void printBody();
+
+ /** \return escaped character*/
+ virtual string maskCharacter ( unsigned char );
+
+ /** initialize tags in specific format according to colouring information provided in DucumentStyle */
+ void initOutputTags();
+
+ /** @param style associated element style
+ @return formatting seqence */
+ string getOpenTag (const ElementStyle &style );
+
+ /** @param styleID current style ID
+ @return matching sequence to begin a new element formatting*/
+ string getKeywordOpenTag ( unsigned int styleID );
+
+ /** @param styleID current style ID
+ @return matching sequence to close element formatting*/
+ string getKeywordCloseTag ( unsigned int styleID );
+
+ /** convert an xterm color value (0-253) to 3 unsigned chars rgb
+ @param color xterm color
+ @param rgb RGB destination string */
+ void xterm2rgb ( unsigned char color, unsigned char* rgb );
+
+ /** fill the colortable for use with rgb2xterm */
+ void maketable();
+
+ /** selects the nearest xterm color for a 3xBYTE rgb value
+ @param RGB colour string */
+ unsigned char rgb2xterm ( unsigned char* rgb );
+
+ /// Flag to determine if colourtable is calculated
+ static bool initialized;
+
+ /// color tzable for nearest match calculation
+ static unsigned char colortable[254][3];
+
+ /// the 6 value iterations in the xterm color cube
+ static const unsigned char valuerange[] ;
+
+ /// 16 basic colors
+ static const unsigned char basic16[16][3];
+ };
+
+}
+#endif
diff --git a/support/highlight/src/gui-qt/Makefile b/support/highlight/src/gui-qt/Makefile
new file mode 100644
index 0000000000..588c30faec
--- /dev/null
+++ b/support/highlight/src/gui-qt/Makefile
@@ -0,0 +1,277 @@
+#############################################################################
+# Makefile for building: ../highlight-gui
+# Generated by qmake (2.01a) (Qt 4.6.2) on: Mi. Mrz 31 16:43:25 2010
+# Project: highlight.pro
+# Template: app
+# Command: /usr/bin/qmake -unix DEFINES+=DATA_DIR=\\\/usr/share/highlight/\\\\ CONFIG_DIR=\\\/etc/highlight/\\\\ DOC_DIR=\\\/usr/share/doc/highlight/\\\ -o Makefile highlight.pro
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = gcc
+CXX = g++
+DEFINES = -DDATA_DIR=\"/usr/share/highlight/\" -DCONFIG_DIR=\"/etc/highlight/\" -DDOC_DIR=\"/usr/share/doc/highlight/\" -DO2 -DQT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
+CFLAGS = -pipe -march=i686 -mtune=generic -O2 -pipe -Wall -W -D_REENTRANT $(DEFINES)
+CXXFLAGS = -pipe -march=i686 -mtune=generic -O2 -pipe -Wall -W -D_REENTRANT $(DEFINES)
+INCPATH = -I/usr/share/qt/mkspecs/linux-g++ -I. -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include -I. -I../core -I. -I.
+LINK = g++
+LFLAGS = -Wl,--hash-style=gnu -Wl,--as-needed -Wl,-O1
+LIBS = $(SUBLIBS) -L/usr/lib -L.. -lhighlight -lQtGui -lQtCore -lpthread
+AR = ar cqs
+RANLIB =
+QMAKE = /usr/bin/qmake
+TAR = tar -cf
+COMPRESS = gzip -9f
+COPY = cp -f
+SED = sed
+COPY_FILE = $(COPY)
+COPY_DIR = $(COPY) -r
+STRIP = strip
+INSTALL_FILE = install -m 644 -p
+INSTALL_DIR = $(COPY_DIR)
+INSTALL_PROGRAM = install -m 755 -p
+DEL_FILE = rm -f
+SYMLINK = ln -f -s
+DEL_DIR = rmdir
+MOVE = mv -f
+CHK_DIR_EXISTS= test -d
+MKDIR = mkdir -p
+
+####### Output directory
+
+OBJECTS_DIR = ./
+
+####### Files
+
+SOURCES = main.cpp \
+ mainwindow.cpp \
+ io_report.cpp \
+ showtextfile.cpp moc_mainwindow.cpp \
+ moc_io_report.cpp \
+ moc_showtextfile.cpp \
+ qrc_highlight-gui.cpp
+OBJECTS = main.o \
+ mainwindow.o \
+ io_report.o \
+ showtextfile.o \
+ moc_mainwindow.o \
+ moc_io_report.o \
+ moc_showtextfile.o \
+ qrc_highlight-gui.o
+DIST = /usr/share/qt/mkspecs/common/g++.conf \
+ /usr/share/qt/mkspecs/common/unix.conf \
+ /usr/share/qt/mkspecs/common/linux.conf \
+ /usr/share/qt/mkspecs/qconfig.pri \
+ /usr/share/qt/mkspecs/features/qt_functions.prf \
+ /usr/share/qt/mkspecs/features/qt_config.prf \
+ /usr/share/qt/mkspecs/features/exclusive_builds.prf \
+ /usr/share/qt/mkspecs/features/default_pre.prf \
+ /usr/share/qt/mkspecs/features/release.prf \
+ /usr/share/qt/mkspecs/features/default_post.prf \
+ /usr/share/qt/mkspecs/features/warn_on.prf \
+ /usr/share/qt/mkspecs/features/qt.prf \
+ /usr/share/qt/mkspecs/features/unix/thread.prf \
+ /usr/share/qt/mkspecs/features/moc.prf \
+ /usr/share/qt/mkspecs/features/resources.prf \
+ /usr/share/qt/mkspecs/features/uic.prf \
+ /usr/share/qt/mkspecs/features/yacc.prf \
+ /usr/share/qt/mkspecs/features/lex.prf \
+ /usr/share/qt/mkspecs/features/include_source_dir.prf \
+ highlight.pro
+QMAKE_TARGET = highlight-gui
+DESTDIR = ../
+TARGET = ../highlight-gui
+
+first: all
+####### Implicit rules
+
+.SUFFIXES: .o .c .cpp .cc .cxx .C
+
+.cpp.o:
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cc.o:
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cxx.o:
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.C.o:
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.c.o:
+ $(CC) -c -include highlight-gui $(CFLAGS) $(INCPATH) -o "$@" "$<"
+
+####### Build rules
+
+all: Makefile $(TARGET)
+
+$(TARGET): ui_mainwindow.h ui_io_report.h ui_showtextfile.h $(OBJECTS)
+ @$(CHK_DIR_EXISTS) ../ || $(MKDIR) ../
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
+
+Makefile: highlight.pro /usr/share/qt/mkspecs/linux-g++/qmake.conf /usr/share/qt/mkspecs/common/g++.conf \
+ /usr/share/qt/mkspecs/common/unix.conf \
+ /usr/share/qt/mkspecs/common/linux.conf \
+ /usr/share/qt/mkspecs/qconfig.pri \
+ /usr/share/qt/mkspecs/features/qt_functions.prf \
+ /usr/share/qt/mkspecs/features/qt_config.prf \
+ /usr/share/qt/mkspecs/features/exclusive_builds.prf \
+ /usr/share/qt/mkspecs/features/default_pre.prf \
+ /usr/share/qt/mkspecs/features/release.prf \
+ /usr/share/qt/mkspecs/features/default_post.prf \
+ /usr/share/qt/mkspecs/features/warn_on.prf \
+ /usr/share/qt/mkspecs/features/qt.prf \
+ /usr/share/qt/mkspecs/features/unix/thread.prf \
+ /usr/share/qt/mkspecs/features/moc.prf \
+ /usr/share/qt/mkspecs/features/resources.prf \
+ /usr/share/qt/mkspecs/features/uic.prf \
+ /usr/share/qt/mkspecs/features/yacc.prf \
+ /usr/share/qt/mkspecs/features/lex.prf \
+ /usr/share/qt/mkspecs/features/include_source_dir.prf \
+ /usr/lib/libQtGui.prl \
+ /usr/lib/libQtCore.prl
+ $(QMAKE) -unix DEFINES+=DATA_DIR=\\\/usr/share/highlight/\\\\ CONFIG_DIR=\\\/etc/highlight/\\\\ DOC_DIR=\\\/usr/share/doc/highlight/\\\ -o Makefile highlight.pro
+/usr/share/qt/mkspecs/common/g++.conf:
+/usr/share/qt/mkspecs/common/unix.conf:
+/usr/share/qt/mkspecs/common/linux.conf:
+/usr/share/qt/mkspecs/qconfig.pri:
+/usr/share/qt/mkspecs/features/qt_functions.prf:
+/usr/share/qt/mkspecs/features/qt_config.prf:
+/usr/share/qt/mkspecs/features/exclusive_builds.prf:
+/usr/share/qt/mkspecs/features/default_pre.prf:
+/usr/share/qt/mkspecs/features/release.prf:
+/usr/share/qt/mkspecs/features/default_post.prf:
+/usr/share/qt/mkspecs/features/warn_on.prf:
+/usr/share/qt/mkspecs/features/qt.prf:
+/usr/share/qt/mkspecs/features/unix/thread.prf:
+/usr/share/qt/mkspecs/features/moc.prf:
+/usr/share/qt/mkspecs/features/resources.prf:
+/usr/share/qt/mkspecs/features/uic.prf:
+/usr/share/qt/mkspecs/features/yacc.prf:
+/usr/share/qt/mkspecs/features/lex.prf:
+/usr/share/qt/mkspecs/features/include_source_dir.prf:
+/usr/lib/libQtGui.prl:
+/usr/lib/libQtCore.prl:
+qmake: FORCE
+ @$(QMAKE) -unix DEFINES+=DATA_DIR=\\\/usr/share/highlight/\\\\ CONFIG_DIR=\\\/etc/highlight/\\\\ DOC_DIR=\\\/usr/share/doc/highlight/\\\ -o Makefile highlight.pro
+
+dist:
+ @$(CHK_DIR_EXISTS) .tmp/highlight-gui1.0.0 || $(MKDIR) .tmp/highlight-gui1.0.0
+ $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/highlight-gui1.0.0/ && $(COPY_FILE) --parents mainwindow.h ../core/ansigenerator.h ../core/bbcodegenerator.h ../core/charcodes.h ../core/codegenerator.h ../core/configurationreader.h ../core/ctagsreader.h ../core/datadir.h ../core/documentstyle.h ../core/elementstyle.h ../core/enums.h ../core/htmlgenerator.h ../core/languagedefinition.h ../core/latexgenerator.h ../core/platform_fs.h ../core/preformatter.h ../core/rtfgenerator.h ../core/stringtools.h ../core/stylecolour.h ../core/svggenerator.h ../core/texgenerator.h ../core/version.h ../core/xhtmlgenerator.h ../core/xmlgenerator.h ../core/xterm256generator.h precomp.h io_report.h showtextfile.h .tmp/highlight-gui1.0.0/ && $(COPY_FILE) --parents highlight-gui.qrc .tmp/highlight-gui1.0.0/ && $(COPY_FILE) --parents main.cpp mainwindow.cpp io_report.cpp showtextfile.cpp .tmp/highlight-gui1.0.0/ && $(COPY_FILE) --parents mainwindow.ui io_report.ui showtextfile.ui .tmp/highlight-gui1.0.0/ && $(COPY_FILE) --parents highlight_de_DE.ts highlight_es_ES.ts .tmp/highlight-gui1.0.0/ && (cd `dirname .tmp/highlight-gui1.0.0` && $(TAR) highlight-gui1.0.0.tar highlight-gui1.0.0 && $(COMPRESS) highlight-gui1.0.0.tar) && $(MOVE) `dirname .tmp/highlight-gui1.0.0`/highlight-gui1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/highlight-gui1.0.0
+
+
+clean:compiler_clean
+ -$(DEL_FILE) $(OBJECTS)
+ -$(DEL_FILE) highlight-gui.gch/c highlight-gui.gch/c++
+ -$(DEL_FILE) *~ core *.core
+
+
+####### Sub-libraries
+
+distclean: clean
+ -$(DEL_FILE) $(TARGET)
+ -$(DEL_FILE) Makefile
+
+
+###### Prefix headers
+highlight-gui.gch/c: precomp.h
+ @$(CHK_DIR_EXISTS) highlight-gui.gch/ || $(MKDIR) highlight-gui.gch/
+ $(CC) $(CFLAGS) $(INCPATH) -x c-header -c precomp.h -o highlight-gui.gch/c
+
+highlight-gui.gch/c++: precomp.h
+ @$(CHK_DIR_EXISTS) highlight-gui.gch/ || $(MKDIR) highlight-gui.gch/
+ $(CXX) $(CXXFLAGS) $(INCPATH) -x c++-header -c precomp.h -o highlight-gui.gch/c++
+
+mocclean: compiler_moc_header_clean compiler_moc_source_clean
+
+mocables: compiler_moc_header_make_all compiler_moc_source_make_all
+
+compiler_moc_header_make_all: moc_mainwindow.cpp moc_io_report.cpp moc_showtextfile.cpp
+compiler_moc_header_clean:
+ -$(DEL_FILE) moc_mainwindow.cpp moc_io_report.cpp moc_showtextfile.cpp
+moc_mainwindow.cpp: mainwindow.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) mainwindow.h -o moc_mainwindow.cpp
+
+moc_io_report.cpp: io_report.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) io_report.h -o moc_io_report.cpp
+
+moc_showtextfile.cpp: showtextfile.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) showtextfile.h -o moc_showtextfile.cpp
+
+compiler_rcc_make_all: qrc_highlight-gui.cpp
+compiler_rcc_clean:
+ -$(DEL_FILE) qrc_highlight-gui.cpp
+qrc_highlight-gui.cpp: highlight-gui.qrc \
+ highlight.xpm \
+ hl_icon2.png
+ /usr/bin/rcc -name highlight-gui highlight-gui.qrc -o qrc_highlight-gui.cpp
+
+compiler_image_collection_make_all: qmake_image_collection.cpp
+compiler_image_collection_clean:
+ -$(DEL_FILE) qmake_image_collection.cpp
+compiler_moc_source_make_all:
+compiler_moc_source_clean:
+compiler_uic_make_all: ui_mainwindow.h ui_io_report.h ui_showtextfile.h
+compiler_uic_clean:
+ -$(DEL_FILE) ui_mainwindow.h ui_io_report.h ui_showtextfile.h
+ui_mainwindow.h: mainwindow.ui
+ /usr/bin/uic mainwindow.ui -o ui_mainwindow.h
+
+ui_io_report.h: io_report.ui
+ /usr/bin/uic io_report.ui -o ui_io_report.h
+
+ui_showtextfile.h: showtextfile.ui
+ /usr/bin/uic showtextfile.ui -o ui_showtextfile.h
+
+compiler_yacc_decl_make_all:
+compiler_yacc_decl_clean:
+compiler_yacc_impl_make_all:
+compiler_yacc_impl_clean:
+compiler_lex_make_all:
+compiler_lex_clean:
+compiler_clean: compiler_moc_header_clean compiler_rcc_clean compiler_uic_clean
+
+####### Compile
+
+main.o: main.cpp mainwindow.h \
+ highlight-gui.gch/c++
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o main.o main.cpp
+
+mainwindow.o: mainwindow.cpp mainwindow.h \
+ ui_mainwindow.h \
+ showtextfile.h \
+ io_report.h \
+ highlight-gui.gch/c++
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o mainwindow.o mainwindow.cpp
+
+io_report.o: io_report.cpp io_report.h \
+ ui_io_report.h \
+ highlight-gui.gch/c++
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o io_report.o io_report.cpp
+
+showtextfile.o: showtextfile.cpp showtextfile.h \
+ ui_showtextfile.h \
+ highlight-gui.gch/c++
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o showtextfile.o showtextfile.cpp
+
+moc_mainwindow.o: moc_mainwindow.cpp highlight-gui.gch/c++
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o moc_mainwindow.o moc_mainwindow.cpp
+
+moc_io_report.o: moc_io_report.cpp highlight-gui.gch/c++
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o moc_io_report.o moc_io_report.cpp
+
+moc_showtextfile.o: moc_showtextfile.cpp highlight-gui.gch/c++
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o moc_showtextfile.o moc_showtextfile.cpp
+
+qrc_highlight-gui.o: qrc_highlight-gui.cpp highlight-gui.gch/c++
+ $(CXX) -c -include highlight-gui $(CXXFLAGS) $(INCPATH) -o qrc_highlight-gui.o qrc_highlight-gui.cpp
+
+####### Install
+
+install: FORCE
+
+uninstall: FORCE
+
+FORCE:
+
diff --git a/support/highlight/src/gui-qt/highlight-gui.qrc b/support/highlight/src/gui-qt/highlight-gui.qrc
new file mode 100644
index 0000000000..cf5f269528
--- /dev/null
+++ b/support/highlight/src/gui-qt/highlight-gui.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/" >
+ <file>highlight.xpm</file>
+ <file>hl_icon2.png</file>
+ </qresource>
+</RCC>
diff --git a/support/highlight/src/gui-qt/highlight.pro b/support/highlight/src/gui-qt/highlight.pro
new file mode 100644
index 0000000000..88676f021f
--- /dev/null
+++ b/support/highlight/src/gui-qt/highlight.pro
@@ -0,0 +1,39 @@
+# -------------------------------------------------
+# Project created by QtCreator 2009-03-03T22:45:06
+# -------------------------------------------------
+TARGET = highlight-gui
+TEMPLATE = app
+INCLUDEPATH += . \
+ ../core/
+win32:CONFIG += static
+CONFIG += precompile_header
+PRECOMPILED_HEADER = precomp.h
+DEFINES += O2 QT
+win32:DESTDIR = ../../
+unix:DESTDIR = ../
+SOURCES += main.cpp \
+ mainwindow.cpp \
+ io_report.cpp \
+ showtextfile.cpp
+HEADERS += mainwindow.h \
+ ../core/*.h \
+ precomp.h \
+ io_report.h \
+ showtextfile.h
+FORMS += mainwindow.ui \
+ io_report.ui \
+ showtextfile.ui
+RESOURCES = highlight-gui.qrc
+TRANSLATIONS = highlight_de_DE.ts highlight_es_ES.ts
+
+win32:RC_FILE = highlight-gui.rc
+win32:LIBS += -L../.. -lhighlight
+unix:LIBS += -L.. -lhighlight
+
+win32:QMAKE_POST_LINK = f:/upx/upx.exe --best ../../highlight-gui.exe
+#unix {
+#DEFINES += DATA_DIR=\\\"/usr/share/highlight\\\" \
+# CONFIG_DIR=\\\"/etc/highlight\\\" \
+# DOC_DIR=\\\"/usr/share/doc/highlight\\\"
+# message("setting unix default paths")
+#}
diff --git a/support/highlight/src/gui-qt/highlight.xpm b/support/highlight/src/gui-qt/highlight.xpm
new file mode 100644
index 0000000000..bc3e73097f
--- /dev/null
+++ b/support/highlight/src/gui-qt/highlight.xpm
@@ -0,0 +1,1173 @@
+/* XPM */
+static char * highlight_xpm[] = {
+"48 48 1122 2",
+" c None",
+". c #0C5C92",
+"+ c #0D5C92",
+"@ c #0F5F94",
+"# c #0F5E94",
+"$ c #126196",
+"% c #156398",
+"& c #156498",
+"* c #18669A",
+"= c #32728E",
+"- c #588D93",
+"; c #62857B",
+"> c #739482",
+", c #748D79",
+"' c #6B7E6D",
+") c #5F847D",
+"! c #37616E",
+"~ c #2A607B",
+"{ c #196699",
+"] c #1B689C",
+"^ c #307799",
+"/ c #549192",
+"( c #609C90",
+"_ c #6AA593",
+": c #68A696",
+"< c #629785",
+"[ c #64937D",
+"} c #547967",
+"| c #546B5C",
+"1 c #53584A",
+"2 c #515549",
+"3 c #3E4747",
+"4 c #2C5F7B",
+"5 c #1B689B",
+"6 c #1E6493",
+"7 c #215E87",
+"8 c #22547C",
+"9 c #275276",
+"0 c #3B5A6F",
+"a c #3E5770",
+"b c #3D5568",
+"c c #365D6D",
+"d c #1C689A",
+"e c #1E6B9E",
+"f c #1E6A9E",
+"g c #3D8091",
+"h c #56A29C",
+"i c #499B92",
+"j c #5FA290",
+"k c #609789",
+"l c #558C7A",
+"m c #598E79",
+"n c #546857",
+"o c #485343",
+"p c #374A3F",
+"q c #4C4231",
+"r c #885229",
+"s c #A5602A",
+"t c #452C1C",
+"u c #2C4156",
+"v c #395373",
+"w c #3F526F",
+"x c #465067",
+"y c #4E4E5C",
+"z c #5A5760",
+"A c #675F5F",
+"B c #655B59",
+"C c #5A5751",
+"D c #406071",
+"E c #22648B",
+"F c #216DA0",
+"G c #448E98",
+"H c #399EA1",
+"I c #3C928D",
+"J c #548378",
+"K c #54887E",
+"L c #3F7872",
+"M c #3E6B63",
+"N c #404F47",
+"O c #41363C",
+"P c #221B20",
+"Q c #392923",
+"R c #BD9C6E",
+"S c #5A321F",
+"T c #2D1716",
+"U c #382B30",
+"V c #504550",
+"W c #65626C",
+"X c #726767",
+"Y c #78655E",
+"Z c #69574F",
+"` c #665D54",
+" . c #3F545E",
+".. c #285D7D",
+"+. c #216D9D",
+"@. c #206DA0",
+"#. c #246FA2",
+"$. c #236FA2",
+"%. c #2470A2",
+"&. c #2370A2",
+"*. c #307797",
+"=. c #498F86",
+"-. c #3C7777",
+";. c #497170",
+">. c #437072",
+",. c #435559",
+"'. c #555E59",
+"). c #58665C",
+"!. c #736852",
+"~. c #7A5334",
+"{. c #472815",
+"]. c #331D17",
+"^. c #674229",
+"/. c #5F3528",
+"(. c #513B44",
+"_. c #463B48",
+":. c #503A3F",
+"<. c #604137",
+"[. c #594133",
+"}. c #616661",
+"|. c #38667E",
+"1. c #256D9A",
+"2. c #2772A4",
+"3. c #2672A4",
+"4. c #2E769D",
+"5. c #469FA3",
+"6. c #477B78",
+"7. c #457073",
+"8. c #326471",
+"9. c #4D5156",
+"0. c #946141",
+"a. c #AC5D2A",
+"b. c #CD6F27",
+"c. c #C36924",
+"d. c #945C2E",
+"e. c #574936",
+"f. c #3C3630",
+"g. c #3B3933",
+"h. c #322523",
+"i. c #746358",
+"j. c #A99E85",
+"k. c #C3B997",
+"l. c #9F967C",
+"m. c #2C729D",
+"n. c #2672A3",
+"o. c #2974A6",
+"p. c #2974A5",
+"q. c #2975A6",
+"r. c #478F95",
+"s. c #4A7B7C",
+"t. c #3C6267",
+"u. c #3F545F",
+"v. c #737779",
+"w. c #CABFA8",
+"x. c #F4CF92",
+"y. c #C5682A",
+"z. c #9F4E21",
+"A. c #52584D",
+"B. c #254749",
+"C. c #223F43",
+"D. c #253A3C",
+"E. c #3A3B39",
+"F. c #ADA589",
+"G. c #DED7AD",
+"H. c #C5B890",
+"I. c #877C68",
+"J. c #4C7386",
+"K. c #2A74A6",
+"L. c #2975A5",
+"M. c #2C77A8",
+"N. c #2C77A7",
+"O. c #2E78A7",
+"P. c #548D85",
+"Q. c #485657",
+"R. c #9D9891",
+"S. c #E0DFD6",
+"T. c #FCFDF4",
+"U. c #FAFDF0",
+"V. c #E8E7D4",
+"W. c #78715E",
+"X. c #1F3E48",
+"Y. c #1B373E",
+"Z. c #1D363C",
+"`. c #233437",
+" + c #343431",
+".+ c #B0A88B",
+"++ c #E6E3B9",
+"@+ c #AF9D7C",
+"#+ c #594E48",
+"$+ c #3A6478",
+"%+ c #2F79A9",
+"&+ c #2F79AA",
+"*+ c #44899D",
+"=+ c #65877E",
+"-+ c #D4D3C3",
+";+ c #F4F3DF",
+">+ c #CFC4A7",
+",+ c #A59174",
+"'+ c #8F7A5E",
+")+ c #3A3839",
+"!+ c #1C2023",
+"~+ c #1A2023",
+"{+ c #161617",
+"]+ c #212120",
+"^+ c #372924",
+"/+ c #69422C",
+"(+ c #BCA88B",
+"_+ c #C1B192",
+":+ c #6C605C",
+"<+ c #455E69",
+"[+ c #327CAB",
+"}+ c #327CAC",
+"|+ c #5B9EAC",
+"1+ c #94B49B",
+"2+ c #8A8F73",
+"3+ c #6E7061",
+"4+ c #474A45",
+"5+ c #353433",
+"6+ c #2C3431",
+"7+ c #32332F",
+"8+ c #303835",
+"9+ c #2A2F2C",
+"0+ c #263535",
+"a+ c #263739",
+"b+ c #3E322A",
+"c+ c #622915",
+"d+ c #632A18",
+"e+ c #653B2D",
+"f+ c #4A3735",
+"g+ c #426780",
+"h+ c #367FAE",
+"i+ c #55A0B6",
+"j+ c #69A59B",
+"k+ c #527E6F",
+"l+ c #446055",
+"m+ c #384741",
+"n+ c #344A43",
+"o+ c #2D3C39",
+"p+ c #333A35",
+"q+ c #293B3A",
+"r+ c #283B3B",
+"s+ c #1D4142",
+"t+ c #22383A",
+"u+ c #274040",
+"v+ c #513122",
+"w+ c #692912",
+"x+ c #5C2715",
+"y+ c #623D2D",
+"z+ c #4C4241",
+"A+ c #387AA2",
+"B+ c #4389B6",
+"C+ c #438AB6",
+"D+ c #4389B7",
+"E+ c #438AB7",
+"F+ c #60A8BE",
+"G+ c #68A49A",
+"H+ c #538373",
+"I+ c #446154",
+"J+ c #416458",
+"K+ c #2F625B",
+"L+ c #265855",
+"M+ c #204E4E",
+"N+ c #21413E",
+"O+ c #405647",
+"P+ c #364238",
+"Q+ c #2D3D37",
+"R+ c #253838",
+"S+ c #283534",
+"T+ c #2C3C3B",
+"U+ c #4A3224",
+"V+ c #672810",
+"W+ c #652B13",
+"X+ c #583022",
+"Y+ c #473129",
+"Z+ c #486D7D",
+"`+ c #5196C0",
+" @ c #5195C0",
+".@ c #6AADC3",
+"+@ c #68B7AE",
+"@@ c #4C8070",
+"#@ c #477666",
+"$@ c #427167",
+"%@ c #306D66",
+"&@ c #255E5D",
+"*@ c #1F5657",
+"=@ c #205559",
+"-@ c #23504E",
+";@ c #477560",
+">@ c #4C6754",
+",@ c #464235",
+"'@ c #303A35",
+")@ c #323C36",
+"!@ c #493E32",
+"~@ c #673219",
+"{@ c #692A10",
+"]@ c #733211",
+"^@ c #633421",
+"/@ c #483129",
+"(@ c #4A6B7C",
+"_@ c #60A1C9",
+":@ c #68ACC9",
+"<@ c #6EB8B4",
+"[@ c #5B9986",
+"}@ c #528374",
+"|@ c #41726C",
+"1@ c #396B65",
+"2@ c #286764",
+"3@ c #226060",
+"4@ c #215E61",
+"5@ c #225356",
+"6@ c #2B5451",
+"7@ c #3E635C",
+"8@ c #466A6A",
+"9@ c #50615A",
+"0@ c #604830",
+"a@ c #5E3821",
+"b@ c #6A3216",
+"c@ c #76300E",
+"d@ c #79320D",
+"e@ c #823B12",
+"f@ c #683318",
+"g@ c #462E24",
+"h@ c #4E6978",
+"i@ c #5FA0C8",
+"j@ c #6DA9CE",
+"k@ c #6DA9CD",
+"l@ c #6FABCC",
+"m@ c #80C5C6",
+"n@ c #5C9480",
+"o@ c #588D7C",
+"p@ c #467970",
+"q@ c #3B726A",
+"r@ c #317570",
+"s@ c #2B6F6C",
+"t@ c #336461",
+"u@ c #2F6C6C",
+"v@ c #396966",
+"w@ c #386B6D",
+"x@ c #3F6A6E",
+"y@ c #49848B",
+"z@ c #605949",
+"A@ c #994B18",
+"B@ c #9A3906",
+"C@ c #843910",
+"D@ c #792D0A",
+"E@ c #93420E",
+"F@ c #8D4213",
+"G@ c #6F3619",
+"H@ c #4E342A",
+"I@ c #54676D",
+"J@ c #6DA8CD",
+"K@ c #7BB0D2",
+"L@ c #75B5B3",
+"M@ c #5C9885",
+"N@ c #5B907C",
+"O@ c #448074",
+"P@ c #548074",
+"Q@ c #3B7971",
+"R@ c #397F7C",
+"S@ c #3D7D79",
+"T@ c #3A736F",
+"U@ c #297172",
+"V@ c #376363",
+"W@ c #477378",
+"X@ c #48767B",
+"Y@ c #586E6B",
+"Z@ c #7C6A4F",
+"`@ c #B6520E",
+" # c #A63E05",
+".# c #8A3206",
+"+# c #873A0C",
+"@# c #984D18",
+"## c #A14F18",
+"$# c #88461E",
+"%# c #4E3327",
+"&# c #5E7177",
+"*# c #7AB0D2",
+"=# c #7BB1D2",
+"-# c #88B8D6",
+";# c #80BACA",
+"># c #5AA58D",
+",# c #5A9D8A",
+"'# c #609484",
+")# c #508077",
+"!# c #599086",
+"~# c #528C82",
+"{# c #4E8980",
+"]# c #3A7875",
+"^# c #266365",
+"/# c #3B797E",
+"(# c #517979",
+"_# c #5F8887",
+":# c #657369",
+"<# c #938462",
+"[# c #C98240",
+"}# c #D26714",
+"|# c #B94B06",
+"1# c #953F0C",
+"2# c #8B3D0F",
+"3# c #AF6427",
+"4# c #AE5D20",
+"5# c #884A23",
+"6# c #4B3227",
+"7# c #7393A0",
+"8# c #96C0DA",
+"9# c #95C0D9",
+"0# c #69B8AF",
+"a# c #4E9B88",
+"b# c #53978A",
+"c# c #59988D",
+"d# c #56827A",
+"e# c #5B8B82",
+"f# c #4D8C83",
+"g# c #357E81",
+"h# c #235F65",
+"i# c #3B7A7B",
+"j# c #5C8580",
+"k# c #5D7D7A",
+"l# c #6B7769",
+"m# c #A99263",
+"n# c #D99E4B",
+"o# c #E68D2A",
+"p# c #DA6D0F",
+"q# c #B95108",
+"r# c #9E4307",
+"s# c #A65115",
+"t# c #A8591D",
+"u# c #AE5E20",
+"v# c #93532A",
+"w# c #503F31",
+"x# c #8EB6CD",
+"y# c #96BFDA",
+"z# c #A3C7DE",
+"A# c #A3C7DF",
+"B# c #8BC7CA",
+"C# c #3EA196",
+"D# c #4B9D92",
+"E# c #499189",
+"F# c #568D86",
+"G# c #4D9189",
+"H# c #478B83",
+"I# c #3A807B",
+"J# c #2D8485",
+"K# c #36797C",
+"L# c #588283",
+"M# c #637F78",
+"N# c #727664",
+"O# c #9C8B60",
+"P# c #DBAE5A",
+"Q# c #EDA53C",
+"R# c #E6811B",
+"S# c #D66609",
+"T# c #B85109",
+"U# c #B3530D",
+"V# c #A54F0F",
+"W# c #A05921",
+"X# c #AA5C1D",
+"Y# c #844D23",
+"Z# c #676861",
+"`# c #A2C6DE",
+" $ c #A4C7DE",
+".$ c #B4D1E4",
+"+$ c #B4D0E4",
+"@$ c #B4D1E3",
+"#$ c #ADCDDB",
+"$$ c #68C3C4",
+"%$ c #329B95",
+"&$ c #35918E",
+"*$ c #298585",
+"=$ c #4B8D85",
+"-$ c #338E8D",
+";$ c #348583",
+">$ c #2B8486",
+",$ c #37949B",
+"'$ c #4B7E7A",
+")$ c #5B7D74",
+"!$ c #647C6F",
+"~$ c #837D5D",
+"{$ c #B9985C",
+"]$ c #EAA53C",
+"^$ c #EE9223",
+"/$ c #E8790F",
+"($ c #D66308",
+"_$ c #B74F07",
+":$ c #A84707",
+"<$ c #98490F",
+"[$ c #9E5F27",
+"}$ c #7F4B22",
+"|$ c #614731",
+"1$ c #9FB5BF",
+"2$ c #B4D0E3",
+"3$ c #CEDFEC",
+"4$ c #CDDFEC",
+"5$ c #9FD4D5",
+"6$ c #2DA5AA",
+"7$ c #169DA1",
+"8$ c #257073",
+"9$ c #2D878A",
+"0$ c #2F8085",
+"a$ c #338A8C",
+"b$ c #3099A1",
+"c$ c #48847F",
+"d$ c #597E78",
+"e$ c #447A7B",
+"f$ c #388692",
+"g$ c #5C7E77",
+"h$ c #9B9871",
+"i$ c #DDA246",
+"j$ c #F19C2A",
+"k$ c #EB7B0E",
+"l$ c #E06B07",
+"m$ c #BF4F03",
+"n$ c #AA4A0A",
+"o$ c #91430E",
+"p$ c #A66122",
+"q$ c #975D29",
+"r$ c #5A3B25",
+"s$ c #7B7B6C",
+"t$ c #C9DCE9",
+"u$ c #CEDFEB",
+"v$ c #E9EEF4",
+"w$ c #E8EEF4",
+"x$ c #E9EFF4",
+"y$ c #82C8CB",
+"z$ c #0B9BAA",
+"A$ c #1C7E89",
+"B$ c #55898A",
+"C$ c #1B96A7",
+"D$ c #4099A1",
+"E$ c #3E8088",
+"F$ c #49797D",
+"G$ c #3D848A",
+"H$ c #2B8193",
+"I$ c #3B838C",
+"J$ c #3F7980",
+"K$ c #828467",
+"L$ c #CA974D",
+"M$ c #E99B32",
+"N$ c #F1901E",
+"O$ c #E16D0C",
+"P$ c #CD5C09",
+"Q$ c #B44D07",
+"R$ c #9A4D19",
+"S$ c #A0632E",
+"T$ c #996A40",
+"U$ c #855F3B",
+"V$ c #675B4B",
+"W$ c #D1D9DB",
+"X$ c #8C96A6",
+"Y$ c #99B9C0",
+"Z$ c #5ECAE5",
+"`$ c #5A99A4",
+" % c #5D9C9F",
+".% c #508188",
+"+% c #448C96",
+"@% c #528A8F",
+"#% c #3D8F9F",
+"$% c #418998",
+"%% c #498B90",
+"&% c #3E7C81",
+"*% c #4F7879",
+"=% c #597B77",
+"-% c #9C8660",
+";% c #D9983E",
+">% c #F39D29",
+",% c #E7760E",
+"'% c #C75307",
+")% c #C0580F",
+"!% c #A34C10",
+"~% c #A26333",
+"{% c #9A6B3D",
+"]% c #A3733E",
+"^% c #715332",
+"/% c #707882",
+"(% c #8B95A5",
+"_% c #284B6C",
+":% c #5BB4C7",
+"<% c #3CB3D7",
+"[% c #61999E",
+"}% c #568588",
+"|% c #4D9298",
+"1% c #368496",
+"2% c #3A8092",
+"3% c #457B82",
+"4% c #467C85",
+"5% c #407E89",
+"6% c #3A7882",
+"7% c #43747B",
+"8% c #4E5951",
+"9% c #AF8444",
+"0% c #F8D25D",
+"a% c #F6961B",
+"b% c #DA6409",
+"c% c #B04A0A",
+"d% c #A1470B",
+"e% c #9D5928",
+"f% c #AB8155",
+"g% c #9A6C3C",
+"h% c #855C2F",
+"i% c #4D5B5B",
+"j% c #284B6B",
+"k% c #6AACCC",
+"l% c #6AABCC",
+"m% c #6AAFC8",
+"n% c #5DCBE8",
+"o% c #3BA5CB",
+"p% c #3F7681",
+"q% c #579CA3",
+"r% c #3F8A9C",
+"s% c #2D879E",
+"t% c #3B8597",
+"u% c #488591",
+"v% c #4A808C",
+"w% c #4A858D",
+"x% c #387B87",
+"y% c #3E6569",
+"z% c #826539",
+"A% c #F4DD72",
+"B% c #FBC342",
+"C% c #EB7A11",
+"D% c #C75C0F",
+"E% c #9F470F",
+"F% c #A3571C",
+"G% c #9D6534",
+"H% c #B1854C",
+"I% c #78522D",
+"J% c #586D6F",
+"K% c #68A9C9",
+"L% c #81CBEB",
+"M% c #80CBEC",
+"N% c #7ED0E1",
+"O% c #56C9ED",
+"P% c #3491B4",
+"Q% c #2696A7",
+"R% c #569CA5",
+"S% c #518A94",
+"T% c #5297A3",
+"U% c #53909D",
+"V% c #538B95",
+"W% c #45838E",
+"X% c #367C87",
+"Y% c #476D6F",
+"Z% c #9B7B40",
+"`% c #F9D14A",
+" & c #FCCD49",
+".& c #F99E20",
+"+& c #E17113",
+"@& c #AA5113",
+"#& c #954C16",
+"$& c #7B441B",
+"%& c #996E3E",
+"&& c #916C40",
+"*& c #67746D",
+"=& c #7BC1DF",
+"-& c #80CBEB",
+";& c #81CBEC",
+">& c #8D948C",
+",& c #87A8AA",
+"'& c #85BFCD",
+")& c #83CEEF",
+"!& c #82DBEA",
+"~& c #44C6EE",
+"{& c #2990B4",
+"]& c #238799",
+"^& c #3A7D8C",
+"/& c #4F9DAA",
+"(& c #4D97A3",
+"_& c #478E9A",
+":& c #3E808D",
+"<& c #38808A",
+"[& c #4C706B",
+"}& c #C2923D",
+"|& c #FBD656",
+"1& c #FBBC2D",
+"2& c #FCB52D",
+"3& c #F38914",
+"4& c #D26613",
+"5& c #7F3E18",
+"6& c #714627",
+"7& c #553722",
+"8& c #6E5439",
+"9& c #789FA8",
+"0& c #81CAE9",
+"a& c #83CEEE",
+"b& c #9D8880",
+"c& c #9A877C",
+"d& c #94887E",
+"e& c #8B9189",
+"f& c #7CCAD3",
+"g& c #37B1E1",
+"h& c #2A809B",
+"i& c #1F7D90",
+"j& c #348D9E",
+"k& c #2791A2",
+"l& c #2E8D9C",
+"m& c #2F8190",
+"n& c #397E85",
+"o& c #4E6964",
+"p& c #AB651D",
+"q& c #FACC3F",
+"r& c #FBBB2E",
+"s& c #FCAF20",
+"t& c #F68C10",
+"u& c #E06D0E",
+"v& c #B3520D",
+"w& c #5A2B19",
+"x& c #463025",
+"y& c #58635F",
+"z& c #71A2B1",
+"A& c #7BC2E2",
+"B& c #A59184",
+"C& c #AC9D91",
+"D& c #AE9D96",
+"E& c #A39088",
+"F& c #81CCDF",
+"G& c #48B1DD",
+"H& c #2181A1",
+"I& c #286877",
+"J& c #238697",
+"K& c #2A8290",
+"L& c #36747C",
+"M& c #3C686B",
+"N& c #54453A",
+"O& c #A8500E",
+"P& c #F6AE23",
+"Q& c #FBC333",
+"R& c #FBA718",
+"S& c #F99610",
+"T& c #EA780B",
+"U& c #CB600D",
+"V& c #843A0C",
+"W& c #473021",
+"X& c #5D7C84",
+"Y& c #73B4D3",
+"Z& c #73B5D5",
+"`& c #C1B398",
+" * c #C4B9A6",
+".* c #BEB29E",
+"+* c #BBB0A1",
+"@* c #A3BEC1",
+"#* c #51BFE7",
+"$* c #287FAD",
+"%* c #2F596B",
+"&* c #3E5150",
+"** c #4C4640",
+"=* c #564338",
+"-* c #572D1B",
+";* c #AE540B",
+">* c #F3970F",
+",* c #FCAE16",
+"'* c #FCAF1E",
+")* c #FAA119",
+"!* c #F1860E",
+"~* c #DC7617",
+"{* c #AC5C19",
+"]* c #6E6758",
+"^* c #6593A4",
+"/* c #6BA8C7",
+"(* c #6BA8C8",
+"_* c #6BA9C8",
+":* c #D4C7A0",
+"<* c #D1CAAC",
+"[* c #CCC5A9",
+"}* c #CBC4AD",
+"|* c #BEC9BE",
+"1* c #57C0E6",
+"2* c #215384",
+"3* c #30262D",
+"4* c #53352B",
+"5* c #663C2B",
+"6* c #5F2A16",
+"7* c #85400E",
+"8* c #DA8518",
+"9* c #F6A51B",
+"0* c #F9A317",
+"a* c #F8A01A",
+"b* c #EE9320",
+"c* c #E18826",
+"d* c #B35916",
+"e* c #884729",
+"f* c #4E565A",
+"g* c #6298B4",
+"h* c #639BBB",
+"i* c #639CBB",
+"j* c #D4C290",
+"k* c #D3C59A",
+"l* c #D2C8A4",
+"m* c #D2C8A8",
+"n* c #BDCBB9",
+"o* c #2B82BB",
+"p* c #3D414F",
+"q* c #432924",
+"r* c #733C1F",
+"s* c #7A360F",
+"t* c #95490F",
+"u* c #713511",
+"v* c #A26022",
+"w* c #CE8E31",
+"x* c #E49224",
+"y* c #CD7C20",
+"z* c #B46922",
+"A* c #93501C",
+"B* c #87411B",
+"C* c #EBAF57",
+"D* c #C17641",
+"E* c #975A3B",
+"F* c #7F6050",
+"G* c #607481",
+"H* c #5B8FAE",
+"I* c #BA9D6E",
+"J* c #C4A673",
+"K* c #C6AE7E",
+"L* c #CBB98C",
+"M* c #8DB2BB",
+"N* c #3076A0",
+"O* c #CAAC63",
+"P* c #CA832D",
+"Q* c #A2510F",
+"R* c #9F4E0D",
+"S* c #854111",
+"T* c #472F34",
+"U* c #4D332A",
+"V* c #663F26",
+"W* c #89552D",
+"X* c #A17142",
+"Y* c #8C5A33",
+"Z* c #B17648",
+"`* c #D68D50",
+" = c #C08C5B",
+".= c #BA875F",
+"+= c #B08765",
+"@= c #9F7354",
+"#= c #996F59",
+"$= c #605E61",
+"%= c #567E99",
+"&= c #5382A2",
+"*= c #5382A1",
+"== c #906D51",
+"-= c #906E4E",
+";= c #B09066",
+">= c #B49467",
+",= c #61A9C9",
+"'= c #8A9E91",
+")= c #E8A840",
+"!= c #C07424",
+"~= c #7A3D11",
+"{= c #8A4F24",
+"]= c #4E383A",
+"^= c #524249",
+"/= c #64473D",
+"(= c #74513C",
+"_= c #BB9A66",
+":= c #CFB17A",
+"<= c #D0AD76",
+"[= c #CFAF7E",
+"}= c #CCAE85",
+"|= c #88624A",
+"1= c #A9704F",
+"2= c #AC6E4C",
+"3= c #B17858",
+"4= c #B78968",
+"5= c #AE927D",
+"6= c #937A70",
+"7= c #75767A",
+"8= c #55748B",
+"9= c #4C7796",
+"0= c #516A74",
+"a= c #516C7D",
+"b= c #5E7682",
+"c= c #678580",
+"d= c #59A1C1",
+"e= c #C18B44",
+"f= c #B67029",
+"g= c #693B1D",
+"h= c #80583A",
+"i= c #907051",
+"j= c #4A3A3B",
+"k= c #5F4840",
+"l= c #725644",
+"m= c #BA9A67",
+"n= c #D5BB7E",
+"o= c #D9C289",
+"p= c #D3B986",
+"q= c #CFB487",
+"r= c #B0916F",
+"s= c #AE7C5A",
+"t= c #BD8A6C",
+"u= c #B37D63",
+"v= c #B48A73",
+"w= c #B9A692",
+"x= c #BAA590",
+"y= c #B29A88",
+"z= c #A39082",
+"A= c #877876",
+"B= c #797C82",
+"C= c #617889",
+"D= c #4F738E",
+"E= c #48708F",
+"F= c #47708F",
+"G= c #436887",
+"H= c #518BA4",
+"I= c #4D4B47",
+"J= c #834B1E",
+"K= c #54473A",
+"L= c #4B626F",
+"M= c #50616B",
+"N= c #5B5E5C",
+"O= c #58504A",
+"P= c #47352C",
+"Q= c #654E3B",
+"R= c #C29C60",
+"S= c #CEB074",
+"T= c #D1BB84",
+"U= c #D5C28F",
+"V= c #D8C79A",
+"W= c #C9AF8E",
+"X= c #CAB195",
+"Y= c #C49779",
+"Z= c #BE8C72",
+"`= c #CBBEA9",
+" - c #C3B29F",
+".- c #C1AC94",
+"+- c #C3B4A4",
+"@- c #B6A79B",
+"#- c #A8968C",
+"$- c #A28E85",
+"%- c #9B887F",
+"&- c #988A83",
+"*- c #858783",
+"=- c #6E7C83",
+"-- c #607685",
+";- c #567284",
+">- c #476C86",
+",- c #436888",
+"'- c #436987",
+")- c #3E6180",
+"!- c #41667F",
+"~- c #49656F",
+"{- c #4A3121",
+"]- c #484A4D",
+"^- c #41627A",
+"/- c #415666",
+"(- c #5C5F5A",
+"_- c #8F7857",
+":- c #AD895A",
+"<- c #BB9D6D",
+"[- c #CEBB8A",
+"}- c #D4C198",
+"|- c #D8CBA6",
+"1- c #D4C8A9",
+"2- c #D1C7AC",
+"3- c #D0C4A9",
+"4- c #CDC2A9",
+"5- c #D5C6AC",
+"6- c #CFC3AC",
+"7- c #CBC6B7",
+"8- c #C4BAAC",
+"9- c #B7A595",
+"0- c #B7A291",
+"a- c #AF9585",
+"b- c #A8937C",
+"c- c #A28E7E",
+"d- c #A6958B",
+"e- c #9B8D88",
+"f- c #87817E",
+"g- c #6F777A",
+"h- c #586E7C",
+"i- c #43637F",
+"j- c #406280",
+"k- c #3B5B78",
+"l- c #3A5979",
+"m- c #3A5977",
+"n- c #3C5872",
+"o- c #3A5A79",
+"p- c #3A5A78",
+"q- c #3A5978",
+"r- c #395A78",
+"s- c #3B5B79",
+"t- c #4A6478",
+"u- c #54626D",
+"v- c #6D665B",
+"w- c #937654",
+"x- c #BCA67B",
+"y- c #C9B689",
+"z- c #CBBC91",
+"A- c #CEC19C",
+"B- c #D1C7A8",
+"C- c #D3CAAD",
+"D- c #D2C3A1",
+"E- c #CBB89A",
+"F- c #D0C6AE",
+"G- c #CBC1AB",
+"H- c #CBC1AF",
+"I- c #C6B7A3",
+"J- c #C1AC96",
+"K- c #C3B399",
+"L- c #BDAB96",
+"M- c #B3A296",
+"N- c #AE9A8E",
+"O- c #A58D81",
+"P- c #A58E82",
+"Q- c #A38E82",
+"R- c #9A8C84",
+"S- c #928D87",
+"T- c #7F8180",
+"U- c #6A7780",
+"V- c #5F707B",
+"W- c #566B78",
+"X- c #506878",
+"Y- c #3C5B78",
+"Z- c #355271",
+"`- c #365371",
+" ; c #4C6271",
+".; c #858679",
+"+; c #AC956D",
+"@; c #A3845D",
+"#; c #A48864",
+"$; c #C4B48F",
+"%; c #D6C9A0",
+"&; c #D6CBA3",
+"*; c #DAD1AE",
+"=; c #D3C6A6",
+"-; c #D7D0B3",
+";; c #D7D2B7",
+">; c #D4CFB8",
+",; c #CFC2A7",
+"'; c #D6CEB3",
+"); c #D0C4AD",
+"!; c #C6BDAC",
+"~; c #C4BDB2",
+"{; c #C0B3A8",
+"]; c #C0B09F",
+"^; c #C4B49F",
+"/; c #BBAA9A",
+"(; c #B39A88",
+"_; c #B19E90",
+":; c #AD9B90",
+"<; c #AD9D90",
+"[; c #AB9A8D",
+"}; c #AA9A8B",
+"|; c #9E9386",
+"1; c #8E8475",
+"2; c #897B6D",
+"3; c #304B6A",
+"4; c #304B69",
+"5; c #3A536D",
+"6; c #5A6A6D",
+"7; c #787567",
+"8; c #9F8C6D",
+"9; c #A28061",
+"0; c #C6A673",
+"a; c #CBB080",
+"b; c #D1BD8C",
+"c; c #D7C89D",
+"d; c #D9CEA8",
+"e; c #DDD8B5",
+"f; c #E1DAB7",
+"g; c #E0DAB7",
+"h; c #DBD5B8",
+"i; c #D9D4B8",
+"j; c #D8D1B7",
+"k; c #CFC1A6",
+"l; c #D2CAB5",
+"m; c #D1C5AB",
+"n; c #CBBEA6",
+"o; c #C2AC94",
+"p; c #B8A18E",
+"q; c #C2B3A0",
+"r; c #BCAD9C",
+"s; c #B4A295",
+"t; c #AF9D8F",
+"u; c #AC998B",
+"v; c #2C4362",
+"w; c #2C4462",
+"x; c #2E4563",
+"y; c #4B5E69",
+"z; c #917962",
+"A; c #9C7758",
+"B; c #956B4A",
+"C; c #B28B5E",
+"D; c #BB9E71",
+"E; c #C7AD7E",
+"F; c #D6C494",
+"G; c #DFD3A9",
+"H; c #D9CFA6",
+"I; c #DCD5B2",
+"J; c #E1DCB7",
+"K; c #DBD1AB",
+"L; c #DFD8B5",
+"M; c #DACDA6",
+"N; c #D9D0B2",
+"O; c #D4C8AA",
+"P; c #D2C7A9",
+"Q; c #D1CAB3",
+"R; c #CAC1AC",
+"S; c #C0B09E",
+"T; c #273C5B",
+"U; c #334761",
+"V; c #293D5B",
+"W; c #887862",
+"X; c #696453",
+"Y; c #494E4D",
+"Z; c #48494F",
+"`; c #5E544F",
+" > c #866D51",
+".> c #A38560",
+"+> c #C7AE7D",
+"@> c #CFAF78",
+"#> c #D0B784",
+"$> c #D6C595",
+"%> c #D7C99D",
+"&> c #D2C293",
+"*> c #D8CA9B",
+"=> c #D9C99B",
+"-> c #D7C89F",
+";> c #D9CEA9",
+">> c #DED5AE",
+",> c #D7CEAE",
+"'> c #D7D1B5",
+")> c #D1C7AD",
+"!> c #B5A398",
+"~> c #A69388",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . + + . + . + + + + + . + . + + + . + . . . . . . + . . . . + + + . + . . + . + . + . . . ",
+"@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ # @ @ @ @ @ @ # @ @ ",
+"@ @ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ",
+"% % % % % & % % % & % % % % % % % % % % % % % % % % % & & % % % % & % % % % % % % % % % % % % & ",
+"* * * * * * * * * * * * * * * * * * * * * = - ; > , ' ) ! ~ { * * * * * * * * * * * * * * * * * ",
+"] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^ / ( _ : < [ } | 1 2 3 4 5 ] ] ] 6 7 8 9 0 a b c d ] ] ] ",
+"e e e e e e e e e e e e e e f e e e g h i j k l m n o p q r s t u v w x y z A B C D E e e e e e ",
+"F F F F F F F F F F F F F F F F F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.F F F F F F @.",
+"#.$.%.#.$.%.%.&.%.%.%.%.&.#.$.#.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.&.%.$.%.%.#.&.%.&.&.",
+"2.3.2.3.3.3.2.3.3.3.2.3.3.3.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.3.3.2.n.3.3.3.3.3.n.3.3.n.",
+"o.o.o.p.o.o.o.o.o.o.o.o.p.o.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.o.p.o.o.o.o.o.K.L.o.o.o.o.o.",
+"M.M.M.M.N.N.N.M.M.N.N.N.M.M.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+N.N.M.M.M.M.M.M.M.N.M.N.N.N.N.",
+"%+%+%+%+&+%+%+%+&+%+&+%+%+%+*+=+-+;+>+,+'+)+!+~+{+]+^+/+(+_+:+<+%+&+&+%+&+%+&+%+%+&+%+%+%+%+%+%+",
+"[+[+}+}+[+[+[+[+[+[+[+[+[+[+|+1+2+3+4+5+6+7+8+9+0+a+b+c+d+e+f+g+[+[+[+[+[+[+[+[+[+[+[+[+[+[+[+[+",
+"h+h+h+h+h+h+h+h+h+h+h+h+h+i+j+k+l+m+n+o+9+p+q+r+s+t+u+v+w+x+y+z+A+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+",
+"B+C+B+D+B+E+D+D+C+B+B+B+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z+B+B+B+D+B+D+B+B+B+D+B+D+B+B+C+",
+"`+`+ @`+`+`+`+`+ @ @ @.@+@@@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@/@(@ @ @`+`+ @`+`+`+`+ @`+ @ @`+`+",
+"_@_@_@_@_@_@_@_@_@_@:@<@[@}@|@1@2@3@4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@i@_@_@_@_@_@_@_@_@_@_@_@_@_@_@",
+"j@j@j@j@k@k@j@k@k@l@m@n@o@p@q@r@s@t@u@v@w@x@y@z@A@B@C@D@E@F@G@H@I@J@j@j@j@k@k@k@k@k@j@k@k@j@k@k@",
+"K@K@K@K@K@K@K@K@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@ #.#+#@###$#%#&#*#K@K@K@K@K@=#=#K@K@K@K@K@K@K@",
+"-#-#-#-#-#-#-#-#;#>#,#'#)#!#~#{#]#^#/#(#_#:#<#[#}#|#1#2#3#4#5#6#7#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#",
+"8#8#8#8#8#8#8#9#0#a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#t#u#v#w#x#8#8#8#8#8#y#8#8#8#8#8#8#8#8#8#",
+"z#z#z#A#z#z#A#B#C#D#E#F#G#H#I#J#K#L#M#N#O#P#Q#R#S#T#U#V#W#X#Y#Z#`#z#z#z#z#z# $z#z#z#z#z#A#A#z#A#",
+".$+$@$.$@$.$#$$$%$&$*$=$-$;$>$,$'$)$!$~${$]$^$/$($_$:$<$[$}$|$1$2$.$@$.$.$.$.$.$@$.$@$.$.$2$.$.$",
+"3$3$4$3$3$3$5$6$7$8$9$0$a$b$c$d$e$f$g$h$i$j$k$l$m$n$o$p$q$r$s$t$3$3$3$3$3$3$3$3$3$3$u$3$3$3$3$3$",
+"v$v$v$v$w$x$y$z$A$B$C$D$E$F$G$H$I$J$K$L$M$N$O$P$Q$R$S$T$U$V$W$w$v$v$v$w$v$v$v$v$v$w$v$v$v$v$v$v$",
+"X$X$X$X$X$Y$Z$`$ %.%+%@%#%$%%%&%*%=%-%;%>%,%'%)%!%~%{%]%^%/%(%X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$",
+"_%_%_%_%_%:%<%[%}%|%1%2%3%4%5%6%7%8%9%0%a%b%c%d%e%f%g%h%i%j%_%_%_%_%_%_%_%_%_%_%_%_%_%_%_%_%_%_%",
+"k%l%k%k%m%n%o%p%q%r%s%t%u%v%w%x%y%z%A%B%C%D%E%F%G%H%I%J%K%l%k%l%k%k%k%l%k%k%l%k%k%k%k%k%k%k%l%k%",
+"L%M%M%M%N%O%P%Q%R%S%T%U%V%W%X%Y%Z%`% &.&+&@&#&$&%&&&*&=&-&L%L%-&-&-&L%-&-&;&L%M%L%;&M%-&M%;&-&M%",
+">&,&'&)&!&~&{&]&^&/&(&_&:&<&[&}&|&1&2&3&4&5&6&7&8&9&0&)&)&a&)&a&a&a&)&)&a&)&a&)&a&)&a&)&)&a&a&a&",
+"b&c&d&e&f&g&h&i&j&k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z&A&A&A&A&A&A&A&A&A&A&A&A&A&A&A&A&A&A&A&A&A&A&A&",
+"B&C&D&E&F&G&H&I&J&K&L&M&N&O&P&Q&R&S&T&U&V&W&X&Y&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&Z&",
+"`& *.*+*@*#*$*%*&***=*-*;*>*,*'*)*!*~*{*]*^*/*(*_*(*(*(*(*(*_*(*(*(*(*_*(*_*(*(*(*_*(*(*(*_*(*(*",
+":*<*[*}*|*1*2*3*4*5*6*7*8*9*0*a*b*c*d*e*f*g*h*h*i*h*i*i*i*i*i*i*i*i*i*i*i*h*i*h*i*i*i*i*i*i*i*i*",
+"j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*A*B*C*D*E*F*G*H*H*H*H*H*H*H*H*H*H*H*H*H*H*H*H*H*H*H*H*H*H*H*H*",
+"I*J*K*L*M*N*O*P*Q*R*S*T*U*V*W*X*Y*Z*`* =.=+=@=#=$=%=&=&=*=*=*=*=*=&=*=&=&=&=&=*=*=&=*=&=*=*=&=*=",
+"==-=;=>=,='=)=!=~={=]=^=/=(=_=:=<=[=}=|=1=2=3=4=5=6=7=8=9=9=9=9=9=9=9=9=9=9=9=9=9=9=9=9=9=9=9=9=",
+"0=a=b=c=d=e=f=g=h=i=j=k=l=m=n=o=p=q=r=s=t=u=v=w=x=y=z=A=B=C=D=E=E=E=E=E=E=E=F=F=E=F=E=F=E=F=F=E=",
+"G=G=G=H=I=J=K=L=M=N=O=P=Q=R=S=T=U=V=W=X=Y=Z=`= -.-+-@-#-$-%-&-*-=---;->-G=G=G=G=G=G=,-,-,-G=G='-",
+")-)-!-~-{-]-)-)-)-)-)-^-/-(-_-:-<-[-}-|-1-2-3-4-5-6-7-8-9-0-a-b-c-d-e-f-g-h-i-j-)-)-)-)-)-)-)-)-",
+"k-l-k-m-n-o-p-q-o-o-o-p-r-s-t-u-v-w-x-y-z-A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X-Y-l-Y-",
+"Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-`- ;.;+;@;#;$;%;&;*;=;-;;;>;,;';);!;~;{;];^;/;(;_;:;<;[;};|;1;2;",
+"3;3;3;3;4;3;3;3;3;3;3;3;3;3;4;3;3;3;3;5;6;7;8;9;0;a;b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u;|;|;",
+"v;v;v;v;v;v;v;v;v;v;v;v;v;v;v;v;v;v;v;v;w;x;y;z;A;B;C;D;E;F;c;G;H;I;J;K;L;M;N;O;P;Q;R;S;|;|;u;|;",
+"T;T;T;T;T;T;T;T;T;T;T;T;T;T;T;T;U;T;T;T;T;T;V;W;X;Y;Z;`; >.>+>@>#>$>%>&>*>=>->;>>>,>'>)>'>!>~>|;"};
diff --git a/support/highlight/src/gui-qt/highlight_de_DE.ts b/support/highlight/src/gui-qt/highlight_de_DE.ts
new file mode 100644
index 0000000000..11f6722383
--- /dev/null
+++ b/support/highlight/src/gui-qt/highlight_de_DE.ts
@@ -0,0 +1,1159 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="de_DE" sourcelanguage="en_US">
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Themes or indent schemes not found.
+Check installation.</source>
+ <translation type="obsolete">Farb- oder Formatierungsvorlagen nicht gefunden.
+Installation prüfen.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="82"/>
+ <source>Initialization error</source>
+ <translation>Initialisierungsfehler</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="83"/>
+ <source>Could not find syntax definitions. Check installation.</source>
+ <translation>Syntaxdefinitionen nicht gefunden.
+Installation prüfen.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="610"/>
+ <source>Tags file error</source>
+ <translation>Tags Dateifehler</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="611"/>
+ <source>Could not read tags information in &quot;%1&quot;</source>
+ <translation>Konnte Tags-Informationen in %1 nicht lesen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="628"/>
+ <location filename="mainwindow.cpp" line="659"/>
+ <source>Output error</source>
+ <translation>Ausgabefehler</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="628"/>
+ <source>Output directory does not exist!</source>
+ <translation>Zielverzeichnis existert nicht!</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="659"/>
+ <source>You must define a style output file!</source>
+ <translation>Sie müssen ein Stylesheet zur Ausgabe angeben!</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="694"/>
+ <source>Language definition error</source>
+ <translation>Fehler in Sprachdefinition</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="695"/>
+ <source>Invalid regular expression in %1:
+%2</source>
+ <translation>Ungültiger regulärer Ausdruck in %1: %2</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="699"/>
+ <source>Unknown syntax</source>
+ <translation>Unbekannte Syntax</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="699"/>
+ <source>Could not convert %1</source>
+ <translation>Konnte %1 nicht konvertieren</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="759"/>
+ <source>Converted %1 files in %2 ms</source>
+ <translation>%1 Dateien in %2 ms konvertiert</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="851"/>
+ <source>Conversion of &quot;%1&quot; not possible.</source>
+ <translation>Konnte &quot;%1&quot; nicht konvertieren.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="851"/>
+ <location filename="mainwindow.cpp" line="951"/>
+ <location filename="mainwindow.cpp" line="962"/>
+ <source>clipboard data</source>
+ <translation>Daten der Zwischenablage</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="950"/>
+ <source>Preview (%1):</source>
+ <translation>Vorschau (%1):</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="953"/>
+ <source>Current syntax: %1</source>
+ <translation>Aktuelle Syntax: %1</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="962"/>
+ <source>Preview of &quot;%1&quot; not possible.</source>
+ <translation>Vorschau von &quot;%1&quot; nicht möglich.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="973"/>
+ <source>Choose a ctags file</source>
+ <translation>Wählen Sie eine ctags Datei</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="999"/>
+ <location filename="mainwindow.cpp" line="1003"/>
+ <location filename="mainwindow.cpp" line="1007"/>
+ <location filename="mainwindow.cpp" line="1012"/>
+ <source>Choose a style include file</source>
+ <translation>Wählen Sie ein Eingabe-Stylesheet</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="1018"/>
+ <source>About providing translations</source>
+ <translation>Ãœbersetzungen bereitstellen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="1019"/>
+ <source>The GUI was developed using the Qt toolkit, and translations may be provided using the tools Qt Linguist and lrelease.
+The highlight.ts file for Linguist resides in the src/gui-qt subdirectory.
+The qm file generated by lrelease has to be saved in gui-files/l10n.
+
+Please send a note to as (at) andre-simon (dot) de if you have issues during translating or if you have finished or updated a translation.</source>
+ <translation>Diese GUI wurde mit dem Qt Toolkit entwickelt, daher werden Ãœbersetzungsdateien mit den Werkzeugen Qt Linguist und lrelease erstellt.
+Die highlight.ts Datei für Linguist befindet sich im src/gui-qt Unterverzeichnis.
+Die von lrelease ausgegebene qm-Datei wird in gui-files/l10n gespeichert.
+
+Bitte senden Sie eine Nachricht an as (at) andre-simon (dot) de, wenn Sie Probleme bei der Ãœbersetzung haben oder wenn Sie eine Ãœbersetzung fertiggestellt bzw. aktualisiert haben.</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindowClass</name>
+ <message>
+ <location filename="mainwindow.ui" line="55"/>
+ <source>Choose the source code files you want to convert.</source>
+ <translation>Wähle Sourcecode-Dateien zur Konvertierung aus.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="61"/>
+ <source>Choose input files</source>
+ <translation>Dateien wählen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="83"/>
+ <source>List of input files.</source>
+ <translation>Liste der Eingabedateien.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="104"/>
+ <source>Remove the selected input files.</source>
+ <translation>Lösche die markierten Dateien aus der Eingabeliste.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="107"/>
+ <source>Clear selection</source>
+ <translation>Auswahl entfernen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="114"/>
+ <source>Remove all input files.</source>
+ <translation>Lösche die Eingabeliste.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="117"/>
+ <source>Clear all</source>
+ <translation>Alle entfernen</translation>
+ </message>
+ <message>
+ <source>Output destination</source>
+ <translation type="obsolete">Zielverzeichnis</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="156"/>
+ <source>Output directory</source>
+ <translation>Zielverzeichnis</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="175"/>
+ <source>Select the output directory.</source>
+ <translation>Wähle das Ausgabeverzeichnis.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="178"/>
+ <location filename="mainwindow.ui" line="808"/>
+ <location filename="mainwindow.ui" line="919"/>
+ <location filename="mainwindow.ui" line="1158"/>
+ <location filename="mainwindow.ui" line="1280"/>
+ <location filename="mainwindow.ui" line="1562"/>
+ <source>...</source>
+ <translation>...</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="187"/>
+ <source>Save output in the input file directories.</source>
+ <translation>Speichere Ausgabe in den Verzeichnissen der Eingabedateien.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="190"/>
+ <source>Write to source directories</source>
+ <translation>In Quellverzeichnisse schreiben</translation>
+ </message>
+ <message>
+ <source>Output options</source>
+ <translation type="obsolete">Ausgabeoptionen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="356"/>
+ <source>General</source>
+ <translation>Allgemein</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="376"/>
+ <source>Output format:</source>
+ <translation>Ausgabeformat:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="398"/>
+ <source>Choose an output format.</source>
+ <translation>Wähle ein Ausgabeformat.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="402"/>
+ <source>HTML</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="407"/>
+ <source>XHTML</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="412"/>
+ <source>LaTeX</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="417"/>
+ <source>TeX</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="422"/>
+ <source>RTF</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="427"/>
+ <source>SVG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="432"/>
+ <source>XML</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="456"/>
+ <source>Add line numbers to the output.</source>
+ <translation>Füge Zeilennummern zur Ausgabe hinzu.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="459"/>
+ <source>Add line numbers</source>
+ <translation>Zeilennummerierung</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="479"/>
+ <source>Select the line number width.</source>
+ <translation>Wähle die Stellenanzahl der Nummerierung.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="500"/>
+ <source>Fill leading space of line numbers with zeroes.</source>
+ <translation>Fülle Zeilennummerierung mit Nullen auf.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="503"/>
+ <source>Pad with zeroes</source>
+ <translation>Zeige führende Nullen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="516"/>
+ <source>Generate output without document header and footer.</source>
+ <translation>Erzeuge Ausgabe ohne Dokumentenkopf und -fußteil.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="519"/>
+ <source>Omit header and footer</source>
+ <translation>Kopf- und Fußteil auslassen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="526"/>
+ <source>Test if input data is not binary.
+Removes Unicode BOM mark.</source>
+ <translation>Stellt sicher, daß die Eingabe nicht binär ist.
+Entfernt den Unicode BOM.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="530"/>
+ <source>Validate input data</source>
+ <translation>Prüfe Eingabedaten</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="539"/>
+ <source>Set the output file ancoding.</source>
+ <translation>Setzt das Encoding.</translation>
+ </message>
+ <message>
+ <source>Encoding:</source>
+ <translation type="obsolete">Encoding:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="549"/>
+ <source>Select or define the encoding.
+The result has to match the input file encoding.</source>
+ <translation>Wähle oder definiere das Ausgabe-Encoding.
+Das Encoding muss mit den Eingabedateien übereinstimmen.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="560"/>
+ <source>ISO-8859-1</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="565"/>
+ <source>ISO-8859-2</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="570"/>
+ <source>ISO-8859-3</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="575"/>
+ <source>ISO-8859-4</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="580"/>
+ <source>ISO-8859-5</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="585"/>
+ <source>ISO-8859-6</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="590"/>
+ <source>ISO-8859-7</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="595"/>
+ <source>ISO-8859-8</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="600"/>
+ <source>ISO-8859-9</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="605"/>
+ <source>ISO-8859-10</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="610"/>
+ <source>ISO-8859-11</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="615"/>
+ <source>ISO-8859-12</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="620"/>
+ <source>ISO-8859-13</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="625"/>
+ <source>ISO-8859-14</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="630"/>
+ <source>ISO-8859-15</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="635"/>
+ <source>UTF-8</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="659"/>
+ <source>Output specific</source>
+ <translation>Format-Optionen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="696"/>
+ <source>HTML options</source>
+ <translation>HTML Optionen</translation>
+ </message>
+ <message>
+ <source>Style</source>
+ <translation type="obsolete">Stylesheets</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="734"/>
+ <location filename="mainwindow.ui" line="1088"/>
+ <location filename="mainwindow.ui" line="1210"/>
+ <location filename="mainwindow.ui" line="1492"/>
+ <source>Include the style information in each output file.</source>
+ <translation>Füge die Stylesheets in jede Ausgabedatei ein.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="737"/>
+ <location filename="mainwindow.ui" line="1495"/>
+ <source>Embed style (CSS)</source>
+ <translation>CSS einbetten</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="747"/>
+ <source>Add CSS information to each tag (do not use CSS class definitions).</source>
+ <translation>Füge Stylesheets in jeden Tag ein (benutze keine CSS Klassen).</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="750"/>
+ <source>Inline CSS</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Style file:</source>
+ <translation type="obsolete">Stylesheet-Datei:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="777"/>
+ <location filename="mainwindow.ui" line="1232"/>
+ <location filename="mainwindow.ui" line="1514"/>
+ <source>Name of the referenced style file.</source>
+ <translation>Name des referenzierten Stylesheets.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="780"/>
+ <location filename="mainwindow.ui" line="1517"/>
+ <source>highlight.css</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Style include file:</source>
+ <translation type="obsolete">Eingabe-Stylesheet:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="798"/>
+ <location filename="mainwindow.ui" line="1552"/>
+ <source>Path of the CSS include file.</source>
+ <translation>Pfad zur CSS-Datei, die ins Stylesheet eingefügt werden soll.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="805"/>
+ <source>Select a CSS include file.</source>
+ <translation>Wähle eine Stylesheet-Eingabedatei.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="819"/>
+ <source>CSS class prefix:</source>
+ <translation>CSS Präfix:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="826"/>
+ <source>Add a CSS class name prefix to avoid namespace clashes.</source>
+ <translation>Definiere einen CSS-Klassennamen, um Kollisionen mit anderen Stylesheets zu vermeiden.</translation>
+ </message>
+ <message>
+ <source>Tags and index files</source>
+ <translation type="obsolete">Tags- und Indexdateien</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="861"/>
+ <source>Generate an index file with hyperlinks to all outputted files.</source>
+ <translation>Erzeuge eine Indexdatei mit Links zu allen Ausgabedateien.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="864"/>
+ <source>Generate index file</source>
+ <translation>Indexdatei erzeugen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="884"/>
+ <source>Read a ctags file and add the included metainformation as tooltips.
+See ctags.sf.net for details.</source>
+ <translation>Lese eine ctags-Datei und füge die Metainformationen als Tooltips hinzu.
+Siehe ctags.sf.net um mehr darüber zu erfahren.</translation>
+ </message>
+ <message>
+ <source>Ctags file:</source>
+ <translation type="obsolete">Ctags Datei:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="903"/>
+ <source>Path of the ctags file.</source>
+ <translation>Pfad der ctags-Datei.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="916"/>
+ <source>Choose a ctags file.</source>
+ <translation>Wähle eine ctags Datei.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="945"/>
+ <source>Misc</source>
+ <translation>Verschiedenes</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="964"/>
+ <source>Add an achor to each line.</source>
+ <translation>Füge Anker zu jeder Zeile hinzu.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="967"/>
+ <source>Add line anchors</source>
+ <translation>Anker einfügen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="974"/>
+ <source>Add the filename as prefix to the anchors.</source>
+ <translation>Füge Dateinamen als Präfix zum Anker hinzu.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="977"/>
+ <source>Include file name in anchor</source>
+ <translation>Dateiname im Anker</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="984"/>
+ <source>Output the lines within an ordered list.</source>
+ <translation>Gib die Zeilen als sortierte Liste aus.</translation>
+ </message>
+ <message>
+ <source>Ordered list</source>
+ <translation type="obsolete">Sortierte Liste</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1001"/>
+ <source>Add &amp;lt;pre&amp;gt; tags to the output, if the flag &quot;No document header and footer&quot; is selected.</source>
+ <translation>Schließe die Ausgabe in &amp;lt;pre&amp;gt;-Tags ein, wenn die Option &quot;Kopf- und Fußteil auslassen&quot; gewählt ist.</translation>
+ </message>
+ <message>
+ <source>Enclose in &lt;pre&gt;</source>
+ <translation type="obsolete">Schließe in &amp;lt;pre&amp;gt; ein</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1044"/>
+ <source>LaTeX options</source>
+ <translation>LaTeX Optionen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1058"/>
+ <source>Replace quotes by dq sequences.</source>
+ <translation>Ersetze Anführungszeichen mit \dq-Sequenzen.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1061"/>
+ <source>Escape quotes</source>
+ <translation>Ersetze Anführungszeichen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1068"/>
+ <source>Make output Babel compatible.</source>
+ <translation>Erzeuge Code, der mit Babel verträglich ist.</translation>
+ </message>
+ <message>
+ <source>Babel compatibility</source>
+ <translation type="obsolete">Babel Kompatibilität</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1078"/>
+ <source>Replace default symbols (brackets, tilde) by nice redefinitions.</source>
+ <translation>Ersetze Standard-Darstellung verschiedener Symbole (Klammern, Tilde) durch schönere Definitionen.</translation>
+ </message>
+ <message>
+ <source>Pretty symbols</source>
+ <translation type="obsolete">Schönere Symbole</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1091"/>
+ <source>Embed style (defs)</source>
+ <translation>Stylesheet einbetten</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1110"/>
+ <source>Name of the referenced style file.</source>
+ <translation>Name des referenzierten Stylesheets.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1113"/>
+ <location filename="mainwindow.ui" line="1235"/>
+ <source>highlight.sty</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Style include:</source>
+ <translation type="obsolete">Eingabe-Stylesheet:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="542"/>
+ <source>Set encoding:</source>
+ <translation>Encoding:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="888"/>
+ <source>Read ctags file:</source>
+ <translation>Lese ctags-Datei:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="987"/>
+ <source>Output as ordered list</source>
+ <translation>Sortierte Liste</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1004"/>
+ <source>Enclose in pre tags</source>
+ <translation>Schließe in pre-Tags ein</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1071"/>
+ <source>Add Babel compatibility</source>
+ <translation>Babel Kompatibilität</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1081"/>
+ <source>Add pretty symbols</source>
+ <translation>Symbole anpassen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="764"/>
+ <location filename="mainwindow.ui" line="1100"/>
+ <location filename="mainwindow.ui" line="1222"/>
+ <location filename="mainwindow.ui" line="1504"/>
+ <source>Stylesheet file:</source>
+ <translation>Stylesheet-Datei:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="141"/>
+ <source>Output destination:</source>
+ <translation>Zielverzeichnis:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1124"/>
+ <location filename="mainwindow.ui" line="1246"/>
+ <location filename="mainwindow.ui" line="1528"/>
+ <source>Stylesheet include file:</source>
+ <translation>Eingabe-Stylesheet:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="957"/>
+ <source>Line numbering options:</source>
+ <translation>Optionen der Zeilennummerierung:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="20"/>
+ <source>Highlight</source>
+ <translation>Highlight</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="49"/>
+ <source>Files</source>
+ <translation>Dateien</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="256"/>
+ <source>Paste clipboard content into the preview window.</source>
+ <translation>Füge Inhalt der Zwischenablage in die Vorschau ein.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="259"/>
+ <source>Paste from clipboard</source>
+ <translation>Aus Zwischenablage einfügen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="297"/>
+ <source>Copy highlighted code into the clipboard.</source>
+ <translation>Kopiere formatierte Ausgabe in die Zwischenablage.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="300"/>
+ <source>Copy preview to clipboard</source>
+ <translation>In Zwischenablage kopieren</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="268"/>
+ <source>Select syntax:</source>
+ <translation>Syntax wählen:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="275"/>
+ <source>Select the correct syntax of the code snippet.</source>
+ <translation>Wähle die zum Text passende Syntax.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="437"/>
+ <source>BBCode</source>
+ <translation>BBCode</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="726"/>
+ <source>Stylesheets</source>
+ <translation>Stylesheets</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="791"/>
+ <source>Include:</source>
+ <translation>Eingabedatei:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="855"/>
+ <source>Index/ctags</source>
+ <translation>Index/ctags</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1148"/>
+ <location filename="mainwindow.ui" line="1270"/>
+ <source>Path of the style include file.</source>
+ <translation>Pfad zur sty-Datei, die ins Stylesheet eingefügt werden soll.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1155"/>
+ <location filename="mainwindow.ui" line="1277"/>
+ <location filename="mainwindow.ui" line="1559"/>
+ <source>Select a style include file.</source>
+ <translation>Wähle eine Stylesheet-Eingabedatei.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1196"/>
+ <source>TeX options</source>
+ <translation>TeX Optionen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1213"/>
+ <source>Embed style (macros)</source>
+ <translation>Stylesheet einbetten</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1318"/>
+ <source>RTF options</source>
+ <translation>RTF Optionen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1332"/>
+ <source>Add character stylesheets with formatting information.
+You can select the stylesheets in your word processor to reformat additional text.</source>
+ <translation>Füge Zeichenvorlagen mit Formatierungsinformationen hinzu.
+Diese können in der Textverarbeitung gewählt werden, um zusätzlichen Text zu formatieren.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1336"/>
+ <source>Add character styles</source>
+ <translation>Zeichenvorlagen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1345"/>
+ <source>Page size:</source>
+ <translation>Papierformat:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1352"/>
+ <source>Select a page size.</source>
+ <translation>Wähle eine Seitengröße aus.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1359"/>
+ <source>A3</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1364"/>
+ <source>A4</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1369"/>
+ <source>A5</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1374"/>
+ <source>B4</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1379"/>
+ <source>B5</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1384"/>
+ <source>B6</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1389"/>
+ <source>Letter</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1394"/>
+ <source>Legal</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1433"/>
+ <source>SVG options</source>
+ <translation>SVG Optionen</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1447"/>
+ <source>Image size:</source>
+ <translation>Bildgröße:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1456"/>
+ <source>Width:</source>
+ <translation>Breite:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1466"/>
+ <source>Enter the SVG width (may contain units).</source>
+ <translation>Gib die Bildbreite ein (kann Größeneinheiten enthalten).</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1473"/>
+ <source>Height:</source>
+ <translation>Höhe:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1483"/>
+ <source>Enter the SVG height (may contain units).</source>
+ <translation>Gib die Bildhöhe ein (kann Größeneinheiten enthalten).</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1588"/>
+ <source>No options defined.</source>
+ <translation>Keine Optionen vorhanden.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1613"/>
+ <source>Formatting</source>
+ <translation>Formatierung</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1627"/>
+ <source>Color theme:</source>
+ <translation>Farbschema:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1643"/>
+ <source>Select a colour theme.</source>
+ <translation>Wähle ein Farbschema.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1654"/>
+ <source>Reformat and indent your code.
+This feature is enabled tor C, C++, C# and Java code.</source>
+ <translation>Formatiere den Eingabecode.
+Diese Funktion kann auf C, C++, C# und Java-Code angewandt werden.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1658"/>
+ <source>Reformat:</source>
+ <translation>Formatieren:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1671"/>
+ <source>Choose a formatting scheme.</source>
+ <translation>Wähle ein Formatierungs-Schema.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1675"/>
+ <source>Allman</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1680"/>
+ <source>Banner</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1685"/>
+ <source>GNU</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1690"/>
+ <source>Java</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1695"/>
+ <source>K&amp;R</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1700"/>
+ <source>Linux</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1705"/>
+ <source>Stroustrup</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1710"/>
+ <source>Whitesmith</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1722"/>
+ <source>Change the keyword case.</source>
+ <translation>Ändere die Groß- und Kleinschreibung, wenn die Eingabesyntax nicht case-sensitive ist.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1725"/>
+ <source>Keyword case:</source>
+ <translation>Schlüsselwort Case:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1738"/>
+ <source>Select a keyword case.</source>
+ <translation>Wähle einen Typ der Groß- und Kleinschreibung.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1742"/>
+ <source>UPPER</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1747"/>
+ <source>lower</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1752"/>
+ <source>Capitalize</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1770"/>
+ <source>Tab width:</source>
+ <translation>Tabulatorbreite:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1780"/>
+ <source>Enter the number of spaces which replace a tab.
+Set the width to 0 to keep tabs.</source>
+ <translation>Gib die Anzahl der Leerzeichen an, die ein Tab ersetzen.
+Setze die Anzahl auf Null, um Tabs auszugeben.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1795"/>
+ <source>Enable line wrapping.</source>
+ <translation>Aktiviere den automatischen Zeilenumbruch.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1798"/>
+ <source>Line wrapping</source>
+ <translation>Zeilenumbruch</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1805"/>
+ <source>Enter the maximum line length.</source>
+ <translation>Gib die maximale Zeilenlänge ein.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1824"/>
+ <source>Indent statements and function parameters after wrapping.</source>
+ <translation>Rücke Kommandos und Funktionsparameter nach dem Umbruch ein.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1827"/>
+ <source>Intelligent wrapping</source>
+ <translation>Intelligenter Umbruch</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1861"/>
+ <source>Font name:</source>
+ <translation>Schriftart:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1871"/>
+ <source>Select or enter the font name.</source>
+ <translation>Wähle oder gib die Schriftart an.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1878"/>
+ <source>Font size:</source>
+ <translation>Schriftgröße:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1894"/>
+ <source>Enter the font size.</source>
+ <translation>Gib die Schriftgröße ein.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1918"/>
+ <source>Preview</source>
+ <translation>Vorschau</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="226"/>
+ <source>Start the conversion of your input files.</source>
+ <translation>Starte die Konvertierung der Eingabedateien.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="229"/>
+ <source>Convert files</source>
+ <translation>Konvertieren</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="239"/>
+ <source>Copy highlighted code of the seleted file into the clipboard.</source>
+ <translation>Kopiere den Inhalt der ausgewählten Datei mit Highlighting in die Zwischenablage.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="250"/>
+ <source>Clipboard</source>
+ <translation>Zwischenablage</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="242"/>
+ <source>Copy file to clipboard</source>
+ <translation>Datei in Zwischenablage</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1943"/>
+ <source>Output progress:</source>
+ <translation>Ausgabefortschritt:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1971"/>
+ <source>&amp;File</source>
+ <translation>&amp;Datei</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1979"/>
+ <source>&amp;Help</source>
+ <translation>&amp;Hilfe</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1996"/>
+ <source>&amp;Open files</source>
+ <translation>Öffne &amp;Dateien</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2001"/>
+ <source>&amp;Exit</source>
+ <translation>&amp;Beenden</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2006"/>
+ <source>&amp;Load</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2011"/>
+ <source>&amp;Save</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2016"/>
+ <source>Load &amp;default project</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2021"/>
+ <source>Readme</source>
+ <translation>Handbuch</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2026"/>
+ <source>&amp;Tips</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2034"/>
+ <source>&amp;Changelog</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2039"/>
+ <source>&amp;License</source>
+ <translation>&amp;Lizenz</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2044"/>
+ <source>&amp;About Highlight</source>
+ <translation>&amp;Ãœber Highlight</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2049"/>
+ <source>About &amp;translations</source>
+ <translation>&amp;Infos zu Ãœbersetzungen</translation>
+ </message>
+</context>
+<context>
+ <name>ShowTextFile</name>
+ <message>
+ <location filename="showtextfile.ui" line="17"/>
+ <source>Show text</source>
+ <translation>Textanzeige</translation>
+ </message>
+ <message>
+ <location filename="showtextfile.ui" line="37"/>
+ <source>TextLabel</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="showtextfile.ui" line="69"/>
+ <source>OK</source>
+ <translation>OK</translation>
+ </message>
+</context>
+<context>
+ <name>io_report</name>
+ <message>
+ <location filename="io_report.ui" line="14"/>
+ <source>Error summary</source>
+ <translation>Fehlerübersicht</translation>
+ </message>
+ <message>
+ <location filename="io_report.ui" line="24"/>
+ <source>Input errors:</source>
+ <translation>Eingabefehler:</translation>
+ </message>
+ <message>
+ <location filename="io_report.ui" line="34"/>
+ <source>Remove files above from input file list</source>
+ <translation>Obige Dateien aus der Eingabeliste löschen</translation>
+ </message>
+ <message>
+ <location filename="io_report.ui" line="48"/>
+ <source>Output errors:</source>
+ <translation>Ausgabefehler:</translation>
+ </message>
+ <message>
+ <location filename="io_report.ui" line="65"/>
+ <source>Reformatting not possible:</source>
+ <translation>Neuformatierung nicht möglich:</translation>
+ </message>
+</context>
+</TS>
diff --git a/support/highlight/src/gui-qt/highlight_es_ES.ts b/support/highlight/src/gui-qt/highlight_es_ES.ts
new file mode 100644
index 0000000000..6349f0590a
--- /dev/null
+++ b/support/highlight/src/gui-qt/highlight_es_ES.ts
@@ -0,0 +1,1156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="es_MX">
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Themes or indent schemes not found.
+Check installation.</source>
+ <translation type="obsolete">Temas o esquemas de indentación no encontrados
+Revise su instalación.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="82"/>
+ <source>Initialization error</source>
+ <translation>Error de inicialización</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="83"/>
+ <source>Could not find syntax definitions. Check installation.</source>
+ <translation>Definiciones de sintaxis no encontradas.
+Revise su instalacion.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="610"/>
+ <source>Tags file error</source>
+ <translation>Error de archivo de etiquetas</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="611"/>
+ <source>Could not read tags information in &quot;%1&quot;</source>
+ <translation>No se pudieron leer las etiquetas de &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="628"/>
+ <location filename="mainwindow.cpp" line="659"/>
+ <source>Output error</source>
+ <translation>Error de salida</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="628"/>
+ <source>Output directory does not exist!</source>
+ <translation>¡Directorio de salida no existe!</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="659"/>
+ <source>You must define a style output file!</source>
+ <translation>¡Debe especificar un archivo de estilo de salida!</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="694"/>
+ <source>Language definition error</source>
+ <translation>Error de definición de lenguaje</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="695"/>
+ <source>Invalid regular expression in %1:
+%2</source>
+ <translation>Expresión regular inválida en %1:
+%2</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="699"/>
+ <source>Unknown syntax</source>
+ <translation>Sintaxis desconocida</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="699"/>
+ <source>Could not convert %1</source>
+ <translation>No se pudo convertir %1</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="759"/>
+ <source>Converted %1 files in %2 ms</source>
+ <translation>Se convirtieron%1 archivos en %2 ms</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="851"/>
+ <source>Conversion of &quot;%1&quot; not possible.</source>
+ <translation>No es posible la conversión de &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="851"/>
+ <location filename="mainwindow.cpp" line="951"/>
+ <location filename="mainwindow.cpp" line="962"/>
+ <source>clipboard data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="950"/>
+ <source>Preview (%1):</source>
+ <translation>Previsualización (%1):</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="953"/>
+ <source>Current syntax: %1</source>
+ <translation>Sintaxis actual: %1</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="962"/>
+ <source>Preview of &quot;%1&quot; not possible.</source>
+ <translation>No es posible previsualizar &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="973"/>
+ <source>Choose a ctags file</source>
+ <translation>Elija un archivo de ctags</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="999"/>
+ <location filename="mainwindow.cpp" line="1003"/>
+ <location filename="mainwindow.cpp" line="1007"/>
+ <location filename="mainwindow.cpp" line="1012"/>
+ <source>Choose a style include file</source>
+ <translation>Elija un archivo de inclusión de estilo</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="1018"/>
+ <source>About providing translations</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="1019"/>
+ <source>The GUI was developed using the Qt toolkit, and translations may be provided using the tools Qt Linguist and lrelease.
+The highlight.ts file for Linguist resides in the src/gui-qt subdirectory.
+The qm file generated by lrelease has to be saved in gui-files/l10n.
+
+Please send a note to as (at) andre-simon (dot) de if you have issues during translating or if you have finished or updated a translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MainWindowClass</name>
+ <message>
+ <location filename="mainwindow.ui" line="55"/>
+ <source>Choose the source code files you want to convert.</source>
+ <translation>Elijir los archivos fuente que desea convertir.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="61"/>
+ <source>Choose input files</source>
+ <translation>Elijir archivos de entrada</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="83"/>
+ <source>List of input files.</source>
+ <translation>Lista de archivos de entrada.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="104"/>
+ <source>Remove the selected input files.</source>
+ <translation>Remover los archivos de entrada seleccionados.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="107"/>
+ <source>Clear selection</source>
+ <translation>Remover seleccionados</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="114"/>
+ <source>Remove all input files.</source>
+ <translation>Remover todos los archivos de entrada.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="117"/>
+ <source>Clear all</source>
+ <translation>Remover todos</translation>
+ </message>
+ <message>
+ <source>Output destination</source>
+ <translation type="obsolete">Destino de salida</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="156"/>
+ <source>Output directory</source>
+ <translation>Directorio de salida</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="175"/>
+ <source>Select the output directory.</source>
+ <translation>Elijir el directorio de salida.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="178"/>
+ <location filename="mainwindow.ui" line="808"/>
+ <location filename="mainwindow.ui" line="919"/>
+ <location filename="mainwindow.ui" line="1158"/>
+ <location filename="mainwindow.ui" line="1280"/>
+ <location filename="mainwindow.ui" line="1562"/>
+ <source>...</source>
+ <translation>...</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="187"/>
+ <source>Save output in the input file directories.</source>
+ <translation>Guardar salida en los directorios de entrada de cada archivo.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="190"/>
+ <source>Write to source directories</source>
+ <translation>Guardar a los directorios de origen</translation>
+ </message>
+ <message>
+ <source>Output options</source>
+ <translation type="obsolete">Opciones de salida</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="356"/>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="376"/>
+ <source>Output format:</source>
+ <translation>Formato de salida:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="398"/>
+ <source>Choose an output format.</source>
+ <translation>Elija un formato de salida.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="402"/>
+ <source>HTML</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="407"/>
+ <source>XHTML</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="412"/>
+ <source>LaTeX</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="417"/>
+ <source>TeX</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="422"/>
+ <source>RTF</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="427"/>
+ <source>SVG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="432"/>
+ <source>XML</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="456"/>
+ <source>Add line numbers to the output.</source>
+ <translation>Agregar números de linea a la salida.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="459"/>
+ <source>Add line numbers</source>
+ <translation>Agregar números de linea</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="479"/>
+ <source>Select the line number width.</source>
+ <translation>Seleccione el ancho de número de linea.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="500"/>
+ <source>Fill leading space of line numbers with zeroes.</source>
+ <translation>Llenar espacio antes de los números de lineas con ceros.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="503"/>
+ <source>Pad with zeroes</source>
+ <translation>Rellenar con ceros</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="516"/>
+ <source>Generate output without document header and footer.</source>
+ <translation>Generar documento de salida con cabecera y pie de página.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="519"/>
+ <source>Omit header and footer</source>
+ <translation>Omitir cabecera y pie de página</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="526"/>
+ <source>Test if input data is not binary.
+Removes Unicode BOM mark.</source>
+ <translation>Probar si los datos de entrada no son binarios.
+Remueve marca BOM de Unicode.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="530"/>
+ <source>Validate input data</source>
+ <translation>Validar datos de entrada</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="539"/>
+ <source>Set the output file ancoding.</source>
+ <translation>Ajuste la codificación del archivo de salida.</translation>
+ </message>
+ <message>
+ <source>Encoding:</source>
+ <translation type="obsolete">Codificación:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="549"/>
+ <source>Select or define the encoding.
+The result has to match the input file encoding.</source>
+ <translation>Elija o defina la codificación.
+El resultado tiene que corresponder a la codificación del archivo de entrada.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="560"/>
+ <source>ISO-8859-1</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="565"/>
+ <source>ISO-8859-2</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="570"/>
+ <source>ISO-8859-3</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="575"/>
+ <source>ISO-8859-4</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="580"/>
+ <source>ISO-8859-5</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="585"/>
+ <source>ISO-8859-6</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="590"/>
+ <source>ISO-8859-7</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="595"/>
+ <source>ISO-8859-8</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="600"/>
+ <source>ISO-8859-9</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="605"/>
+ <source>ISO-8859-10</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="610"/>
+ <source>ISO-8859-11</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="615"/>
+ <source>ISO-8859-12</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="620"/>
+ <source>ISO-8859-13</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="625"/>
+ <source>ISO-8859-14</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="630"/>
+ <source>ISO-8859-15</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="635"/>
+ <source>UTF-8</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="659"/>
+ <source>Output specific</source>
+ <translation>Esoecificas de salida</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="696"/>
+ <source>HTML options</source>
+ <translation>Opciones de HTML</translation>
+ </message>
+ <message>
+ <source>Style</source>
+ <translation type="obsolete">Hoja de estilo</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="734"/>
+ <location filename="mainwindow.ui" line="1088"/>
+ <location filename="mainwindow.ui" line="1210"/>
+ <location filename="mainwindow.ui" line="1492"/>
+ <source>Include the style information in each output file.</source>
+ <translation>Incluir la información de estilo en cada archivo de salida.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="737"/>
+ <location filename="mainwindow.ui" line="1495"/>
+ <source>Embed style (CSS)</source>
+ <translation>Incrustar estilo (CSS)</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="747"/>
+ <source>Add CSS information to each tag (do not use CSS class definitions).</source>
+ <translation>Agregar información de CSS a cada etiqueta (no utilizar definiciones de clase de CSS).</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="750"/>
+ <source>Inline CSS</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Style file:</source>
+ <translation type="obsolete">Archivo de estilo:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="777"/>
+ <location filename="mainwindow.ui" line="1232"/>
+ <location filename="mainwindow.ui" line="1514"/>
+ <source>Name of the referenced style file.</source>
+ <translation>Nombre del archivo de estilo citado.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="780"/>
+ <location filename="mainwindow.ui" line="1517"/>
+ <source>highlight.css</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Style include file:</source>
+ <translation type="obsolete">Archivo de estilo a incluir:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="798"/>
+ <location filename="mainwindow.ui" line="1552"/>
+ <source>Path of the CSS include file.</source>
+ <translation>Ruta del archivo CSS a incluir.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="805"/>
+ <source>Select a CSS include file.</source>
+ <translation>Seleccionar un archivo CSS a incluir.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="819"/>
+ <source>CSS class prefix:</source>
+ <translation>Prefijo de clase de CSS:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="826"/>
+ <source>Add a CSS class name prefix to avoid namespace clashes.</source>
+ <translation>Agregue un prefijo de nombre de clase de CSS para evitar conflictos.</translation>
+ </message>
+ <message>
+ <source>Tags and index files</source>
+ <translation type="obsolete">Archivos de etiquetas e índice</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="861"/>
+ <source>Generate an index file with hyperlinks to all outputted files.</source>
+ <translation>Generar un archivo de indice con enlaces a todos los archivos de salida.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="864"/>
+ <source>Generate index file</source>
+ <translation>Generar archivo de índice</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="884"/>
+ <source>Read a ctags file and add the included metainformation as tooltips.
+See ctags.sf.net for details.</source>
+ <translation>Leer un archivo de ctags y agregar la metainformación incluida como aviso emergente.
+Vea ctags.sf.net para más detalles.</translation>
+ </message>
+ <message>
+ <source>Ctags file:</source>
+ <translation type="obsolete">Archivo de ctags:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="903"/>
+ <source>Path of the ctags file.</source>
+ <translation>Ruta del archivo de ctags.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="916"/>
+ <source>Choose a ctags file.</source>
+ <translation>Elijir un archivo de ctags.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="945"/>
+ <source>Misc</source>
+ <translation>Miscelaneo</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="964"/>
+ <source>Add an achor to each line.</source>
+ <translation>Agregar una ancla a cada linea.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="967"/>
+ <source>Add line anchors</source>
+ <translation>Agregar ancla por linea</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="974"/>
+ <source>Add the filename as prefix to the anchors.</source>
+ <translation>Agregar el nombre de archivo como prefijo a las anclas.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="977"/>
+ <source>Include file name in anchor</source>
+ <translation>Incluir el nombre de archivo en el ancla</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="984"/>
+ <source>Output the lines within an ordered list.</source>
+ <translation>Producir las lineas de salida dentro de una lista ordenada.</translation>
+ </message>
+ <message>
+ <source>Ordered list</source>
+ <translation type="obsolete">Lista ordenada</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1001"/>
+ <source>Add &amp;lt;pre&amp;gt; tags to the output, if the flag &quot;No document header and footer&quot; is selected.</source>
+ <translation>Agregar etiquetas &amp;lt;pre&amp;gt; a la salida, si la opción &quot;Sin cabecera ni pie de página&quot; está seleccionada.</translation>
+ </message>
+ <message>
+ <source>Enclose in &lt;pre&gt;</source>
+ <translation type="obsolete">Meter entre &amp;lt;pre&amp;gt;</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1044"/>
+ <source>LaTeX options</source>
+ <translation>Opciones de LaTeX</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1058"/>
+ <source>Replace quotes by dq sequences.</source>
+ <translation>Reemplazar comillas por sucesiones de dobles comillas.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1061"/>
+ <source>Escape quotes</source>
+ <translation>Sobrepasar comillas</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1068"/>
+ <source>Make output Babel compatible.</source>
+ <translation>Hacer que la salida se compatible con Babel.</translation>
+ </message>
+ <message>
+ <source>Babel compatibility</source>
+ <translation type="obsolete">Compatibilidad con Babel</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1078"/>
+ <source>Replace default symbols (brackets, tilde) by nice redefinitions.</source>
+ <translation>Reemplazar símbolos por defecto (llaves, corchetes, tildes) por redefiniciones apropiadas.</translation>
+ </message>
+ <message>
+ <source>Pretty symbols</source>
+ <translation type="obsolete">Símbolos lindos</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1091"/>
+ <source>Embed style (defs)</source>
+ <translation>Incrustar estilo</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1110"/>
+ <source>Name of the referenced style file.</source>
+ <translation>Nombre del archivo de estilo citado.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1113"/>
+ <location filename="mainwindow.ui" line="1235"/>
+ <source>highlight.sty</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Style include:</source>
+ <translation type="obsolete">Incluir estilo:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="542"/>
+ <source>Set encoding:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="141"/>
+ <source>Output destination:</source>
+ <translation>Destino de salida</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="764"/>
+ <location filename="mainwindow.ui" line="1100"/>
+ <location filename="mainwindow.ui" line="1222"/>
+ <location filename="mainwindow.ui" line="1504"/>
+ <source>Stylesheet file:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1124"/>
+ <location filename="mainwindow.ui" line="1246"/>
+ <location filename="mainwindow.ui" line="1528"/>
+ <source>Stylesheet include file:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="888"/>
+ <source>Read ctags file:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="20"/>
+ <source>Highlight</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="49"/>
+ <source>Files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="256"/>
+ <source>Paste clipboard content into the preview window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="259"/>
+ <source>Paste from clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="297"/>
+ <source>Copy highlighted code into the clipboard.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="300"/>
+ <source>Copy preview to clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="268"/>
+ <source>Select syntax:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="275"/>
+ <source>Select the correct syntax of the code snippet.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="437"/>
+ <source>BBCode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="726"/>
+ <source>Stylesheets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="791"/>
+ <source>Include:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="855"/>
+ <source>Index/ctags</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="957"/>
+ <source>Line numbering options:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="987"/>
+ <source>Output as ordered list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1004"/>
+ <source>Enclose in pre tags</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1071"/>
+ <source>Add Babel compatibility</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1081"/>
+ <source>Add pretty symbols</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1148"/>
+ <location filename="mainwindow.ui" line="1270"/>
+ <source>Path of the style include file.</source>
+ <translation>Ruta del archivo de estilo a incluir.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1155"/>
+ <location filename="mainwindow.ui" line="1277"/>
+ <location filename="mainwindow.ui" line="1559"/>
+ <source>Select a style include file.</source>
+ <translation>Seleccione un archivo de estilo a incluir.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1196"/>
+ <source>TeX options</source>
+ <translation>Opciones de TeX</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1213"/>
+ <source>Embed style (macros)</source>
+ <translation>Estilo de incrustación (macros)</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1318"/>
+ <source>RTF options</source>
+ <translation>Opciones de RTF</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1332"/>
+ <source>Add character stylesheets with formatting information.
+You can select the stylesheets in your word processor to reformat additional text.</source>
+ <translation>Agregar hojas de estilo de caracteres con informacion de formato.
+Puede selecionar la hoja de estilo en su procesador de textos para dar formato nuevamente a texto adicional.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1336"/>
+ <source>Add character styles</source>
+ <translation>Agregar estilos de caracteres</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1345"/>
+ <source>Page size:</source>
+ <translation>Tamaño de paǵina:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1352"/>
+ <source>Select a page size.</source>
+ <translation>Seleccionar un tamaño de página.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1359"/>
+ <source>A3</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1364"/>
+ <source>A4</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1369"/>
+ <source>A5</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1374"/>
+ <source>B4</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1379"/>
+ <source>B5</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1384"/>
+ <source>B6</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1389"/>
+ <source>Letter</source>
+ <translation>Carta</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1394"/>
+ <source>Legal</source>
+ <translation>Oficio</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1433"/>
+ <source>SVG options</source>
+ <translation>Opciones de SVG</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1447"/>
+ <source>Image size:</source>
+ <translation>Tamaño de la imagen:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1456"/>
+ <source>Width:</source>
+ <translation>Ancho:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1466"/>
+ <source>Enter the SVG width (may contain units).</source>
+ <translation>Introducir el ancho de SVG (puede incluir unidades).</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1473"/>
+ <source>Height:</source>
+ <translation>Alto:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1483"/>
+ <source>Enter the SVG height (may contain units).</source>
+ <translation>Introducir el alto de SVG (puede incluir unidades).</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1588"/>
+ <source>No options defined.</source>
+ <translation>No hay opciones definidas.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1613"/>
+ <source>Formatting</source>
+ <translation>Formato</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1627"/>
+ <source>Color theme:</source>
+ <translation>Tema de color:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1643"/>
+ <source>Select a colour theme.</source>
+ <translation>Seleccionar un tema de color.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1654"/>
+ <source>Reformat and indent your code.
+This feature is enabled tor C, C++, C# and Java code.</source>
+ <translation>Dar formato nuevamente e indentar su código.
+Esta propiedad esta habilitada para código en C, C++, C# y Java.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1658"/>
+ <source>Reformat:</source>
+ <translation>Dar formato nuevamente:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1671"/>
+ <source>Choose a formatting scheme.</source>
+ <translation>Elija un esquema de formato.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1675"/>
+ <source>Allman</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1680"/>
+ <source>Banner</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1685"/>
+ <source>GNU</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1690"/>
+ <source>Java</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1695"/>
+ <source>K&amp;R</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1700"/>
+ <source>Linux</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1705"/>
+ <source>Stroustrup</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1710"/>
+ <source>Whitesmith</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1722"/>
+ <source>Change the keyword case.</source>
+ <translation>Cambiar mayúsculas/minúsculas en palabras reservadas.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1725"/>
+ <source>Keyword case:</source>
+ <translation>Mayúsculas/minúsculas de palabras reservadas:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1738"/>
+ <source>Select a keyword case.</source>
+ <translation>Seleccione un estilo de mayúsculas/minúsculas.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1742"/>
+ <source>UPPER</source>
+ <translation>MAYÚSCULAS</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1747"/>
+ <source>lower</source>
+ <translation>minúsculas</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1752"/>
+ <source>Capitalize</source>
+ <translation>Primera Letra Mayúscula</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1770"/>
+ <source>Tab width:</source>
+ <translation>Ancho de tabulador:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1780"/>
+ <source>Enter the number of spaces which replace a tab.
+Set the width to 0 to keep tabs.</source>
+ <translation>Introducir el número de espacios que reemplazaran un tabulador.
+En caso de ser 0 se mantendrán los tabuladores.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1795"/>
+ <source>Enable line wrapping.</source>
+ <translation>Habilitar romper lineas.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1798"/>
+ <source>Line wrapping</source>
+ <translation>Romper lineas</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1805"/>
+ <source>Enter the maximum line length.</source>
+ <translation>Introducir longitud máxima de linea.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1824"/>
+ <source>Indent statements and function parameters after wrapping.</source>
+ <translation>Indentar instrucciones y parámetros de funciones después de romper la linea.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1827"/>
+ <source>Intelligent wrapping</source>
+ <translation>Rompido inteligente</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1861"/>
+ <source>Font name:</source>
+ <translation>Nombre de la fuente:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1871"/>
+ <source>Select or enter the font name.</source>
+ <translation>Seleccionar o introduzcir el nombre de la fuente.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1878"/>
+ <source>Font size:</source>
+ <translation>Tamaño de la fuente:</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1894"/>
+ <source>Enter the font size.</source>
+ <translation>Introducir el tamaño de la fuente.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1918"/>
+ <source>Preview</source>
+ <translation>Previsualización</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="226"/>
+ <source>Start the conversion of your input files.</source>
+ <translation>Comenzar la conversión de los archivos de entrada.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="229"/>
+ <source>Convert files</source>
+ <translation>Convertir archivos</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="239"/>
+ <source>Copy highlighted code of the seleted file into the clipboard.</source>
+ <translation>Copiar codigo resaltado del archivo seleccionado al portapapeles.</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="250"/>
+ <source>Clipboard</source>
+ <translation>Portapapeles</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="242"/>
+ <source>Copy file to clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1943"/>
+ <source>Output progress:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1971"/>
+ <source>&amp;File</source>
+ <translation>&amp;Archivo</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1979"/>
+ <source>&amp;Help</source>
+ <translation>Ay&amp;uda</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="1996"/>
+ <source>&amp;Open files</source>
+ <translation>Ab&amp;rir archivos</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2001"/>
+ <source>&amp;Exit</source>
+ <translation>&amp;Salir</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2006"/>
+ <source>&amp;Load</source>
+ <translation>&amp;Cargar</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2011"/>
+ <source>&amp;Save</source>
+ <translation>&amp;Guardar</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2016"/>
+ <source>Load &amp;default project</source>
+ <translation>Cargar proyecto por &amp;defecto</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2021"/>
+ <source>Readme</source>
+ <translation>Leeme</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2026"/>
+ <source>&amp;Tips</source>
+ <translation>A&amp;visos</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2034"/>
+ <source>&amp;Changelog</source>
+ <translation>&amp;Bitácora de cambios</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2039"/>
+ <source>&amp;License</source>
+ <translation>&amp;Licencia</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2044"/>
+ <source>&amp;About Highlight</source>
+ <translation>&amp;Acerca de Highlight</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="2049"/>
+ <source>About &amp;translations</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ShowTextFile</name>
+ <message>
+ <location filename="showtextfile.ui" line="17"/>
+ <source>Show text</source>
+ <translation>Mostrar texto</translation>
+ </message>
+ <message>
+ <location filename="showtextfile.ui" line="37"/>
+ <source>TextLabel</source>
+ <translation>EtiquetaDeTexto</translation>
+ </message>
+ <message>
+ <location filename="showtextfile.ui" line="69"/>
+ <source>OK</source>
+ <translation>OK</translation>
+ </message>
+</context>
+<context>
+ <name>io_report</name>
+ <message>
+ <location filename="io_report.ui" line="14"/>
+ <source>Error summary</source>
+ <translation>Resumen de Error</translation>
+ </message>
+ <message>
+ <location filename="io_report.ui" line="24"/>
+ <source>Input errors:</source>
+ <translation>Errores de entrada:</translation>
+ </message>
+ <message>
+ <location filename="io_report.ui" line="34"/>
+ <source>Remove files above from input file list</source>
+ <translation>Remover archivos mencionados de la lista de archivos de entrada</translation>
+ </message>
+ <message>
+ <location filename="io_report.ui" line="48"/>
+ <source>Output errors:</source>
+ <translation>Errores de salida:</translation>
+ </message>
+ <message>
+ <location filename="io_report.ui" line="65"/>
+ <source>Reformatting not possible:</source>
+ <translation>No es posible dar formato nuevamente:</translation>
+ </message>
+</context>
+</TS>
diff --git a/support/highlight/src/gui-qt/hl_icon2.png b/support/highlight/src/gui-qt/hl_icon2.png
new file mode 100644
index 0000000000..dd182616ff
--- /dev/null
+++ b/support/highlight/src/gui-qt/hl_icon2.png
Binary files differ
diff --git a/support/highlight/src/gui-qt/hl_icon_exe.ico b/support/highlight/src/gui-qt/hl_icon_exe.ico
new file mode 100644
index 0000000000..9b11e75a07
--- /dev/null
+++ b/support/highlight/src/gui-qt/hl_icon_exe.ico
Binary files differ
diff --git a/support/highlight/src/gui-qt/io_report.cpp b/support/highlight/src/gui-qt/io_report.cpp
new file mode 100644
index 0000000000..a534cb916a
--- /dev/null
+++ b/support/highlight/src/gui-qt/io_report.cpp
@@ -0,0 +1,68 @@
+/***************************************************************************
+ io_report.cpp
+ -------------------
+ begin : Mo 16.03.2009
+ copyright : (C) 2009 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "io_report.h"
+#include "ui_io_report.h"
+
+io_report::io_report(QWidget *parent) :
+ QDialog(parent),
+ m_ui(new Ui::io_report)
+{
+ m_ui->setupUi(this);
+}
+
+io_report::~io_report()
+{
+ delete m_ui;
+}
+
+void io_report::changeEvent(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ m_ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+void io_report::addInputErrors(QStringList & list){
+ m_ui->listInputErrors->clear();
+ m_ui->listInputErrors->addItems(list);
+}
+
+ void io_report::addOutputErrors(QStringList & list){
+ m_ui->listOutputErrors->clear();
+ m_ui->listOutputErrors->addItems(list);
+ }
+ void io_report::addReformatErrors(QStringList & list){
+ m_ui->listReformatErrors->clear();
+ m_ui->listReformatErrors->addItems(list);
+ }
+
+bool io_report::removeInputErrorFiles() {
+ return m_ui->cbRemoveFiles->isChecked();
+}
diff --git a/support/highlight/src/gui-qt/io_report.h b/support/highlight/src/gui-qt/io_report.h
new file mode 100644
index 0000000000..369d8fc5cc
--- /dev/null
+++ b/support/highlight/src/gui-qt/io_report.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ io_report.h
+ -------------------
+ begin : Mo 16.03.2009
+ copyright : (C) 2009 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef IO_REPORT_H
+#define IO_REPORT_H
+
+#include <QtGui/QDialog>
+
+namespace Ui {
+ class io_report;
+}
+
+class io_report : public QDialog {
+ Q_OBJECT
+ Q_DISABLE_COPY(io_report)
+public:
+ explicit io_report(QWidget *parent = 0);
+ virtual ~io_report();
+
+ void addInputErrors(QStringList & list);
+ void addOutputErrors(QStringList & list);
+ void addReformatErrors(QStringList & list);
+
+ bool removeInputErrorFiles();
+
+
+protected:
+ virtual void changeEvent(QEvent *e);
+
+private:
+ Ui::io_report *m_ui;
+};
+
+#endif // IO_REPORT_H
diff --git a/support/highlight/src/gui-qt/io_report.ui b/support/highlight/src/gui-qt/io_report.ui
new file mode 100644
index 0000000000..6b4d96159c
--- /dev/null
+++ b/support/highlight/src/gui-qt/io_report.ui
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>io_report</class>
+ <widget class="QDialog" name="io_report">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>436</width>
+ <height>372</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Error summary</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="highlight-gui.qrc">
+ <normaloff>:/hl_icon2.png</normaloff>:/hl_icon2.png</iconset>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Input errors:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listInputErrors"/>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbRemoveFiles">
+ <property name="text">
+ <string>Remove files above from input file list</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Output errors:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listOutputErrors"/>
+ </item>
+ <item>
+ <widget class="Line" name="line_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Reformatting not possible:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listReformatErrors"/>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="highlight-gui.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>io_report</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>io_report</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/support/highlight/src/gui-qt/main.cpp b/support/highlight/src/gui-qt/main.cpp
new file mode 100644
index 0000000000..027f87a2c6
--- /dev/null
+++ b/support/highlight/src/gui-qt/main.cpp
@@ -0,0 +1,54 @@
+/***************************************************************************
+ main.cpp
+ -------------------
+ begin : Mo 16.03.2009
+ copyright : (C) 2009 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <QtGui/QApplication>
+#include <QTranslator>
+#include <QLocale>
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ QTranslator translator;
+ #ifdef DATA_DIR
+ translator.load(QString("%1/gui_files/l10n/highlight_%2").arg(DATA_DIR).arg(QLocale::system().name()));
+ #else
+ translator.load(QString("%1/gui_files/l10n/highlight_%2").arg(QDir::currentPath()).arg(QLocale::system().name()));
+ #endif
+ app.installTranslator(&translator);
+
+ MainWindow w;
+
+ QStringList args=QCoreApplication::arguments();
+ if (args.count()>1){
+ args.removeFirst(); // drop highlight-gui.exe path
+ w.addInputFiles(args);
+ }
+
+ w.show();
+ return app.exec();
+}
diff --git a/support/highlight/src/gui-qt/mainwindow.cpp b/support/highlight/src/gui-qt/mainwindow.cpp
new file mode 100644
index 0000000000..06abcd29dd
--- /dev/null
+++ b/support/highlight/src/gui-qt/mainwindow.cpp
@@ -0,0 +1,1080 @@
+/***************************************************************************
+ mainwindow.cpp
+ -------------------
+ begin : Mo 16.03.2009
+ copyright : (C) 2009 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <memory>
+#include <algorithm>
+
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include "version.h"
+#include "showtextfile.h"
+#include "io_report.h"
+
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent), ui(new Ui::MainWindowClass)
+{
+ ui->setupUi(this);
+ this->setWindowTitle(QString("Highlight %1").arg( HIGHLIGHT_VERSION));
+
+ // Read file open filter
+#ifdef DATA_DIR
+ QFile filterDef(QString(DATA_DIR) + "/gui_files/ext/fileopenfilter.conf");
+#else
+ QFile filterDef(QDir::currentPath()+"/gui_files/ext/fileopenfilter.conf");
+#endif
+
+ QRegExp rx("(\\S+)\\s?\\(\\*\\.([\\w\\d]+)");
+
+ if (filterDef.open(QIODevice::ReadOnly | QIODevice::Text)){
+ QTextStream in(&filterDef);
+ QString line;
+
+ QStringList syntaxPair;
+ while (!in.atEnd()) {
+ line = in.readLine();
+ fileOpenFilter+=line;
+ fileOpenFilter+=";;";
+ if( rx.indexIn(line)!=-1){
+ syntaxPair = rx.capturedTexts();
+ ui->comboSelectSyntax->addItem(syntaxPair[1], syntaxPair[2]);
+ }
+ }
+ } else {
+ fileOpenFilter="All files (*)";
+ }
+ // fill themes combo
+#ifdef DATA_DIR
+ QDir themesDir(QString(DATA_DIR) + "/themes");
+#else
+ QDir themesDir(QDir::currentPath()+"/themes");
+#endif
+ QStringList themes = themesDir.entryList(QStringList("*.style"), QDir::Files, QDir::Name);
+ for (QStringList::const_iterator constIterator = themes.constBegin();
+ constIterator != themes.constEnd(); ++constIterator) {
+ ui->comboTheme->addItem(QString(*constIterator).section('.',0, 0));
+ }
+
+ // load syntax mappings
+ if (!loadFileTypeConfig(&extensions, &shebangs)){
+ QMessageBox::warning(this, tr("Initialization error"),
+ tr("Could not find syntax definitions. Check installation."));
+ }
+
+ QObject::connect(ui->pbOpenFiles, SIGNAL(clicked()), this, SLOT(openFiles()));
+ QObject::connect(ui->action_Open_files, SIGNAL(triggered()), this, SLOT(openFiles()));
+
+ QObject::connect(ui->cbWrite2Src, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbIncLineNo, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbWrapping, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbEncoding, SIGNAL(clicked()), this, SLOT(plausibility()));
+
+ QObject::connect(ui->comboFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(plausibility()));
+ QObject::connect(ui->cbReformat, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbKwCase, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbHTMLEmbedStyle, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbHTMLAnchors, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbHTMLEmbedStyle, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbHTMLInlineCSS, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbHTMLCtags, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbLATEXEmbedStyle, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbTEXEmbedStyle, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbSVGEmbedStyle, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->cbFragment, SIGNAL(clicked()), this, SLOT(plausibility()));
+ QObject::connect(ui->tabIOSelection, SIGNAL(currentChanged(int)), this, SLOT(plausibility()));
+
+ QObject::connect(ui->lvInputFiles, SIGNAL(itemSelectionChanged()), this, SLOT(updatePreview()));
+ QObject::connect(ui->cbIncLineNo, SIGNAL(clicked()), this, SLOT(updatePreview()));
+ QObject::connect(ui->cbKwCase, SIGNAL(clicked()), this, SLOT(updatePreview()));
+ QObject::connect(ui->cbPadZeroes, SIGNAL(clicked()), this, SLOT(updatePreview()));
+ QObject::connect(ui->cbReformat, SIGNAL(clicked()), this, SLOT(updatePreview()));
+ QObject::connect(ui->cbWrapping, SIGNAL(clicked()), this, SLOT(updatePreview()));
+ QObject::connect(ui->cbAdvWrapping, SIGNAL(clicked()), this, SLOT(updatePreview()));
+ QObject::connect(ui->cbValidateInput, SIGNAL(clicked()), this, SLOT(updatePreview()));
+ QObject::connect(ui->cbEncoding, SIGNAL(clicked()), this, SLOT(updatePreview()));
+ QObject::connect(ui->comboEncoding, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
+
+ QObject::connect(ui->comboFontName, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
+ QObject::connect(ui->comboKwCase, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
+ QObject::connect(ui->comboReformat, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
+ QObject::connect(ui->comboTheme, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
+ QObject::connect(ui->comboSelectSyntax, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
+
+ QObject::connect(ui->sbLineNoWidth, SIGNAL(valueChanged(int)), this, SLOT(updatePreview()));
+ QObject::connect(ui->leFontSize, SIGNAL(textChanged(QString)), this, SLOT(updatePreview()));
+
+ setAcceptDrops(true);
+
+ readSettings();
+ plausibility();
+}
+
+MainWindow::~MainWindow()
+{
+ writeSettings();
+ delete ui;
+}
+
+void MainWindow::openFiles(){
+ QFileDialog dialog(this, "Select one or more files to open",
+ "",
+ fileOpenFilter);
+ dialog.setFileMode(QFileDialog::ExistingFiles);
+ dialog.setViewMode(QFileDialog::Detail);
+
+ if (dialog.exec()) {
+ addInputFiles(dialog.selectedFiles());
+ }
+}
+
+void MainWindow::selectSingleFile(QLineEdit* edit, const QString& title, const QString& filter){
+ QFileDialog dialog(this, title,
+ "",
+ filter);
+ dialog.setFileMode(QFileDialog::ExistingFile);
+ dialog.setViewMode(QFileDialog::Detail);
+
+ if (dialog.exec()) {
+ edit->setText(dialog.selectedFiles().first());
+ }
+}
+
+void MainWindow::addInputFiles(const QStringList& list){
+ for (QStringList::const_iterator constIterator = list.constBegin();
+ constIterator != list.constEnd(); ++constIterator) {
+ if (ui->lvInputFiles->findItems ( *constIterator, Qt::MatchExactly ).empty()) {
+ ui->lvInputFiles->addItem(*constIterator);
+ }
+ }
+}
+
+void MainWindow::on_pbClearSelection_clicked(){
+ QList<QListWidgetItem *> selectedItems = ui->lvInputFiles->selectedItems();
+ for (int i = 0; i < selectedItems.size(); ++i) {
+ delete selectedItems.at(i);
+ }
+}
+
+void MainWindow::on_pbOutputDest_clicked(){
+ QFileDialog dialog(this, "Select destination directory", "");
+ dialog.setFileMode(QFileDialog::Directory);
+ if (dialog.exec() && !dialog.selectedFiles().empty()) {
+ ui->leOutputDest->setText(dialog.selectedFiles().at(0));
+ }
+}
+
+ void MainWindow::writeSettings()
+ {
+ QSettings settings(QSettings::IniFormat, QSettings::UserScope,
+ "andre-simon.de", "highlight-gui");
+
+ settings.beginGroup("MainWindow");
+ settings.setValue("size", size());
+ settings.setValue("pos", pos());
+ settings.endGroup();
+
+ settings.beginGroup("input");
+ QStringList inFiles;
+ for (int i=0;i<ui->lvInputFiles->count();i++){
+ inFiles<<ui->lvInputFiles->item(i)->text();
+ }
+ const char* name="objectName";
+ settings.setValue(ui->lvInputFiles->property(name).toString(),
+ inFiles);
+ settings.setValue(ui->leOutputDest->property(name).toString(),
+ ui->leOutputDest->text());
+ settings.setValue(ui->cbWrite2Src->property(name).toString(),
+ ui->cbWrite2Src->isChecked());
+ settings.setValue(ui->cbAdvWrapping->property(name).toString(),
+ ui->cbAdvWrapping->isChecked());
+ settings.setValue(ui->cbEncoding->property(name).toString(),
+ ui->cbEncoding->isChecked());
+ settings.setValue(ui->cbFragment->property(name).toString(),
+ ui->cbFragment->isChecked());
+ settings.setValue(ui->cbHTMLAnchors->property(name).toString(),
+ ui->cbHTMLAnchors->isChecked());
+ settings.setValue(ui->cbHTMLCtags->property(name).toString(),
+ ui->cbHTMLCtags->isChecked());
+ settings.setValue(ui->cbHTMLEmbedStyle->property(name).toString(),
+ ui->cbHTMLEmbedStyle->isChecked());
+ settings.setValue(ui->cbHTMLEnclosePreTags->property(name).toString(),
+ ui->cbHTMLEnclosePreTags->isChecked());
+ settings.setValue(ui->cbHTMLFileNameAnchor->property(name).toString(),
+ ui->cbHTMLFileNameAnchor->isChecked());
+ settings.setValue(ui->cbHTMLIndex->property(name).toString(),
+ ui->cbHTMLIndex->isChecked());
+ settings.setValue(ui->cbHTMLInlineCSS->property(name).toString(),
+ ui->cbHTMLInlineCSS->isChecked());
+ settings.setValue(ui->cbHTMLOrderedList->property(name).toString(),
+ ui->cbHTMLOrderedList->isChecked());
+ settings.setValue(ui->cbIncLineNo->property(name).toString(),
+ ui->cbIncLineNo->isChecked());
+ settings.setValue(ui->cbKwCase->property(name).toString(),
+ ui->cbKwCase->isChecked());
+ settings.setValue(ui->cbLATEXBabel->property(name).toString(),
+ ui->cbLATEXBabel->isChecked());
+ settings.setValue(ui->cbLATEXEscQuotes->property(name).toString(),
+ ui->cbLATEXEscQuotes->isChecked());
+ settings.setValue(ui->cbLATEXPrettySymbols->property(name).toString(),
+ ui->cbLATEXPrettySymbols->isChecked());
+ settings.setValue(ui->cbPadZeroes->property(name).toString(),
+ ui->cbPadZeroes->isChecked());
+ settings.setValue(ui->cbReformat->property(name).toString(),
+ ui->cbReformat->isChecked());
+ settings.setValue(ui->cbRTFCharStyles->property(name).toString(),
+ ui->cbRTFCharStyles->isChecked());
+ settings.setValue(ui->cbWrapping->property(name).toString(),
+ ui->cbWrapping->isChecked());
+ settings.setValue(ui->cbValidateInput->property(name).toString(),
+ ui->cbValidateInput->isChecked());
+
+ settings.setValue(ui->comboFormat->property(name).toString(),
+ ui->comboFormat->currentIndex());
+ settings.setValue(ui->comboKwCase->property(name).toString(),
+ ui->comboKwCase->currentIndex());
+ settings.setValue(ui->comboReformat->property(name).toString(),
+ ui->comboReformat->currentIndex());
+ settings.setValue(ui->comboRTFPageSize->property(name).toString(),
+ ui->comboRTFPageSize->currentIndex());
+ settings.setValue(ui->comboTheme->property(name).toString(),
+ ui->comboTheme->currentIndex());
+ settings.setValue(ui->comboEncoding->property(name).toString(),
+ ui->comboEncoding->currentText());
+ settings.setValue(ui->comboFontName->property(name).toString(),
+ ui->comboFontName->currentText());
+ settings.setValue(ui->comboSelectSyntax->property(name).toString(),
+ ui->comboSelectSyntax->currentIndex());
+
+ settings.setValue(ui->leHTMLCtagsFile->property(name).toString(),
+ ui->leHTMLCtagsFile->text());
+ settings.setValue(ui->leHTMLStyleFile->property(name).toString(),
+ ui->leHTMLStyleFile->text());
+ settings.setValue(ui->leHTMLStyleIncFile->property(name).toString(),
+ ui->leHTMLStyleIncFile->text());
+ settings.setValue(ui->leLATEXStyleFile->property(name).toString(),
+ ui->leLATEXStyleFile->text());
+ settings.setValue(ui->leLATEXStyleIncFile->property(name).toString(),
+ ui->leLATEXStyleIncFile->text());
+ settings.setValue(ui->leTEXStyleFile->property(name).toString(),
+ ui->leTEXStyleFile->text());
+ settings.setValue(ui->leTEXStyleIncFile->property(name).toString(),
+ ui->leTEXStyleIncFile->text());
+ settings.setValue(ui->leSVGStyleFile->property(name).toString(),
+ ui->leSVGStyleFile->text());
+ settings.setValue(ui->leSVGStyleIncFile->property(name).toString(),
+ ui->leSVGStyleIncFile->text());
+ settings.setValue(ui->cbSVGEmbedStyle->property(name).toString(),
+ ui->cbSVGEmbedStyle->isChecked());
+ settings.setValue(ui->cbLATEXEmbedStyle->property(name).toString(),
+ ui->cbLATEXEmbedStyle->isChecked());
+ settings.setValue(ui->cbTEXEmbedStyle->property(name).toString(),
+ ui->cbTEXEmbedStyle->isChecked());
+ settings.setValue(ui->leSVGHeight->property(name).toString(),
+ ui->leSVGHeight->text());
+ settings.setValue(ui->leSVGWidth->property(name).toString(),
+ ui->leSVGWidth->text());
+ settings.setValue(ui->leFontSize->property(name).toString(),
+ ui->leFontSize->text());
+ settings.setValue(ui->sbLineLength->property(name).toString(),
+ ui->sbLineLength->value());
+ settings.setValue(ui->sbTabWidth->property(name).toString(),
+ ui->sbTabWidth->value());
+ settings.setValue(ui->tabWidget->property(name).toString(),
+ ui->tabWidget->currentIndex());
+ settings.setValue(ui->leHTMLCssPrefix->property(name).toString(),
+ ui->leHTMLCssPrefix->text());
+ settings.setValue(ui->tabIOSelection->property(name).toString(),
+ ui->tabIOSelection->currentIndex());
+
+
+ settings.endGroup();
+ }
+
+ void MainWindow::readSettings()
+ {
+ QSettings settings(QSettings::IniFormat, QSettings::UserScope,
+ "andre-simon.de", "highlight-gui");
+
+ settings.beginGroup("MainWindow");
+ resize(settings.value("size", QSize(400, 400)).toSize());
+ move(settings.value("pos", QPoint(200, 200)).toPoint());
+ settings.endGroup();
+
+ settings.beginGroup("input");
+ const char* name="objectName";
+ ui->lvInputFiles->addItems( settings.value(ui->lvInputFiles->property(name).toString()).toStringList() );
+ ui->leOutputDest->setText(settings.value(ui->leOutputDest->property(name).toString()).toString());
+ ui->cbWrite2Src->setChecked(settings.value(ui->cbWrite2Src->property(name).toString()).toBool());
+ ui->cbAdvWrapping->setChecked(settings.value(ui->cbAdvWrapping->property(name).toString()).toBool());
+ ui->cbEncoding->setChecked(settings.value(ui->cbEncoding->property(name).toString()).toBool());
+ ui->cbFragment->setChecked(settings.value(ui->cbFragment->property(name).toString()).toBool());
+ ui->cbHTMLAnchors->setChecked(settings.value(ui->cbHTMLAnchors->property(name).toString()).toBool());
+ ui->cbHTMLCtags->setChecked(settings.value(ui->cbHTMLCtags->property(name).toString()).toBool());
+ ui->cbHTMLEmbedStyle->setChecked(settings.value(ui->cbHTMLEmbedStyle->property(name).toString()).toBool());
+ ui->cbHTMLEnclosePreTags->setChecked(settings.value(ui->cbHTMLEnclosePreTags->property(name).toString()).toBool());
+ ui->cbHTMLFileNameAnchor->setChecked(settings.value(ui->cbHTMLFileNameAnchor->property(name).toString()).toBool());
+ ui->cbHTMLIndex->setChecked(settings.value(ui->cbHTMLIndex->property(name).toString()).toBool());
+ ui->cbHTMLInlineCSS->setChecked(settings.value(ui->cbHTMLInlineCSS->property(name).toString()).toBool());
+ ui->cbHTMLOrderedList->setChecked(settings.value(ui->cbHTMLOrderedList->property(name).toString()).toBool());
+ ui->cbIncLineNo->setChecked(settings.value(ui->cbIncLineNo->property(name).toString()).toBool());
+ ui->cbKwCase->setChecked(settings.value(ui->cbKwCase->property(name).toString()).toBool());
+ ui->cbLATEXBabel->setChecked(settings.value(ui->cbLATEXBabel->property(name).toString()).toBool());
+ ui->cbLATEXEscQuotes->setChecked(settings.value(ui->cbLATEXEscQuotes->property(name).toString()).toBool());
+ ui->cbLATEXPrettySymbols->setChecked(settings.value(ui->cbLATEXPrettySymbols->property(name).toString()).toBool());
+
+ ui->cbPadZeroes->setChecked(settings.value(ui->cbPadZeroes->property(name).toString()).toBool());
+ ui->cbReformat->setChecked(settings.value(ui->cbReformat->property(name).toString()).toBool());
+ ui->cbRTFCharStyles->setChecked(settings.value(ui->cbRTFCharStyles->property(name).toString()).toBool());
+ ui->cbWrapping->setChecked(settings.value(ui->cbWrapping->property(name).toString()).toBool());
+ ui->cbValidateInput->setChecked(settings.value(ui->cbValidateInput->property(name).toString()).toBool());
+
+ ui->comboEncoding->insertItem(0, settings.value(ui->comboEncoding->property(name).toString()).toString());
+ ui->comboEncoding->setCurrentIndex(0);
+ ui->comboFontName->insertItem(0, settings.value(ui->comboFontName->property(name).toString()).toString());
+ ui->comboFontName->setCurrentIndex(0);
+ ui->comboFormat->setCurrentIndex(settings.value(ui->comboFormat->property(name).toString()).toInt());
+ ui->comboKwCase->setCurrentIndex(settings.value(ui->comboKwCase->property(name).toString()).toInt());
+ ui->comboReformat->setCurrentIndex(settings.value(ui->comboReformat->property(name).toString()).toInt());
+ ui->comboRTFPageSize->setCurrentIndex(settings.value(ui->comboRTFPageSize->property(name).toString()).toInt());
+ ui->comboTheme->setCurrentIndex(settings.value(ui->comboTheme->property(name).toString()).toInt());
+ ui->comboSelectSyntax->setCurrentIndex(settings.value(ui->comboSelectSyntax->property(name).toString()).toInt());
+
+ ui->leHTMLCtagsFile->setText(settings.value(ui->leHTMLCtagsFile->property(name).toString()).toString());
+ ui->leHTMLStyleFile->setText(settings.value(ui->leHTMLStyleFile->property(name).toString()).toString());
+ ui->leHTMLStyleIncFile->setText(settings.value(ui->leHTMLStyleIncFile->property(name).toString()).toString());
+ ui->leLATEXStyleFile->setText(settings.value(ui->leLATEXStyleFile->property(name).toString()).toString());
+ ui->leTEXStyleFile->setText(settings.value(ui->leTEXStyleFile->property(name).toString()).toString());
+ ui->leLATEXStyleIncFile->setText(settings.value(ui->leLATEXStyleIncFile->property(name).toString()).toString());
+ ui->leTEXStyleIncFile->setText(settings.value(ui->leTEXStyleIncFile->property(name).toString()).toString());
+ ui->leSVGHeight->setText(settings.value(ui->leSVGHeight->property(name).toString()).toString());
+ ui->leSVGWidth->setText(settings.value(ui->leSVGWidth->property(name).toString()).toString());
+ ui->leFontSize->setText(settings.value(ui->leFontSize->property(name).toString()).toString());
+ ui->leHTMLCssPrefix->setText(settings.value(ui->leHTMLCssPrefix->property(name).toString()).toString());
+ ui->sbLineLength->setValue(settings.value(ui->sbLineLength->property(name).toString()).toInt());
+ ui->sbTabWidth->setValue(settings.value(ui->sbTabWidth->property(name).toString()).toInt());
+ ui->cbTEXEmbedStyle->setChecked(settings.value(ui->cbTEXEmbedStyle->property(name).toString()).toBool());
+ ui->cbLATEXEmbedStyle->setChecked(settings.value(ui->cbLATEXEmbedStyle->property(name).toString()).toBool());
+ ui->cbSVGEmbedStyle->setChecked(settings.value(ui->cbSVGEmbedStyle->property(name).toString()).toBool());
+ ui->tabWidget->setCurrentIndex(settings.value(ui->tabWidget->property(name).toString()).toInt());
+ ui->tabIOSelection->setCurrentIndex(settings.value(ui->tabIOSelection->property(name).toString()).toInt());
+
+ settings.endGroup();
+ }
+
+bool MainWindow::loadFileTypeConfig(StringMap* extMap, StringMap* shebangMap) {
+ if (!extMap || !shebangMap) return false;
+
+#ifdef CONFIG_DIR
+ QString filetypesPath = QDir::toNativeSeparators(QString("%1/filetypes.conf").arg(CONFIG_DIR));
+#else
+ QString filetypesPath = QDir::toNativeSeparators(QString("%1/filetypes.conf").arg(QDir::currentPath()));
+#endif
+
+ ConfigurationReader config(filetypesPath.toStdString());
+ if (config.found())
+ {
+ stringstream values;
+ string paramName, paramVal;
+ for (unsigned int i=0;i<config.getParameterNames().size();i++){
+ paramName = config.getParameterNames()[i];
+ if (paramName.find("ext") != string::npos){
+ values.str(StringTools::change_case(config.getParameter(paramName)));
+ paramName = StringTools::getParantheseVal(paramName);
+ while (values >> paramVal) {
+ extMap->insert(make_pair( paramVal, paramName));
+ }
+ values.clear();
+ } else if (paramName.find("shebang") != string::npos){
+ values.str(config.getParameter(paramName)) ;
+ paramName = StringTools::getParantheseVal(paramName);
+ while (values >> paramVal) {
+ shebangMap->insert(make_pair( paramVal, paramName));
+ }
+ values.clear();
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+ string MainWindow::analyzeFile(const string& file){
+ ifstream inFile(file.c_str());
+ string firstLine;
+ getline (inFile, firstLine);
+ StringMap::iterator it;
+ for (it=shebangs.begin(); it!=shebangs.end();it++){
+ if (Pattern::matches(it->first, firstLine)) return it->second;
+ }
+ return "";
+}
+
+string MainWindow::getFileType(const string& suffix, const string &inputFile)
+{
+ string lcSuffix = StringTools::change_case(suffix);
+ string fileType = (extensions.count(lcSuffix)) ? extensions[lcSuffix] : lcSuffix ;
+ if (!fileType.empty()) return fileType;
+ return analyzeFile(inputFile);
+}
+
+string MainWindow::getFileSuffix(const string& fileName)
+{
+ unsigned int ptPos=fileName.rfind(".");
+ return (ptPos == string::npos) ? "" : fileName.substr(ptPos+1,
+ fileName.length());
+}
+
+void MainWindow::on_action_Exit_triggered()
+{
+ this->close();
+}
+
+void MainWindow::on_action_About_Highlight_triggered()
+{
+ QMessageBox::about( this, "About Highlight",
+ QString("Highlight is a code to formatted text converter.\n\n"
+ "Highlight GUI %1\n"
+ "(C) 2002-2010 Andre Simon <andre.simon1 at gmx.de>\n\n"
+ "Artistic Style Classes\n(C) 1998-2002 Tal Davidson\n"
+ "(C) 2006-2009 Jim Pattee <jimp03 at email.com>\n\n"
+ "Regex library\n(C) 2003-2008 Jeffery Stuart <stuart at cs.unr.edu>\n\n"
+ "Built with Qt version %2\n\n"
+ "Released under the terms of the GNU GPL license.\n\n"
+ "The highlight logo is based on the image \"Alcedo Atthis\" by Lukasz Lukasik.\n"
+ "The original was published under the terms of the GNU FDL in the Wikimedia Commons database.\n\n"
+ "Updates: http://www.andre-simon.de/\n").arg(HIGHLIGHT_VERSION).arg(QString(qVersion ())) );
+}
+
+ highlight::OutputType MainWindow::getOutputType(){
+
+ switch (ui->comboFormat->currentIndex()){
+ case 0: return highlight::HTML;
+ case 1: return highlight::XHTML;
+ case 2: return highlight::LATEX;
+ case 3: return highlight::TEX;
+ case 4: return highlight::RTF;
+ case 5: return highlight::SVG;
+ case 6: return highlight::XML;
+ case 7: return highlight::BBCODE;
+ }
+ return highlight::HTML;
+}
+
+ QString MainWindow::getOutFileSuffix(){
+ switch (ui->comboFormat->currentIndex()) {
+ case 0: return ".html";
+ case 1: return ".xhtml";
+ case 2:
+ case 3: return ".tex";
+ case 4: return ".rtf";
+ case 5: return ".svg";
+ case 6: return ".xml";
+ case 7: return ".bbcode";
+ }
+ return ".html";
+}
+
+
+void MainWindow::applyCtrlValues(highlight::CodeGenerator* generator, bool previewMode){
+ if (!generator) return;
+
+ highlight::OutputType outType=getOutputType();
+
+ if (!previewMode){
+ QLineEdit * styleIncFile=NULL;
+ QLineEdit * styleOutFile=NULL;
+ QCheckBox * embedStyle=NULL;
+
+ switch(outType) {
+ case highlight::HTML:
+ case highlight::XHTML: styleIncFile = ui->leHTMLStyleIncFile;
+ styleOutFile = ui->leHTMLStyleFile;
+ embedStyle = ui->cbHTMLEmbedStyle;
+ break;
+ case highlight::LATEX:
+ styleIncFile = ui->leLATEXStyleIncFile;
+ styleOutFile = ui->leLATEXStyleFile;
+ embedStyle = ui->cbLATEXEmbedStyle;
+ break;
+ case highlight::TEX: styleIncFile = ui->leTEXStyleIncFile;
+ styleOutFile = ui->leTEXStyleFile;
+ embedStyle = ui->cbTEXEmbedStyle;
+ break;
+ case highlight::SVG: styleIncFile = ui->leSVGStyleIncFile;
+ styleOutFile = ui->leSVGStyleFile;
+ embedStyle = ui->cbSVGEmbedStyle;
+ break;
+ default: break;
+ }
+ if (styleIncFile)
+ generator->setStyleInputPath(QDir::toNativeSeparators(styleIncFile->text()).toStdString());
+ if (styleOutFile)
+ generator->setStyleOutputPath(styleOutFile->text().toStdString());
+ if (embedStyle)
+ generator->setIncludeStyle(embedStyle->isChecked());
+
+ generator->setFragmentCode(ui->cbFragment->isChecked());
+
+ generator->setHTMLAttachAnchors(ui->cbHTMLAnchors->isChecked());
+ generator->setHTMLOrderedList(ui->cbHTMLOrderedList->isChecked());
+ generator->setHTMLInlineCSS(ui->cbHTMLInlineCSS->isChecked() && ui->cbHTMLInlineCSS->isEnabled());
+ generator->setHTMLEnclosePreTag(ui->cbHTMLEnclosePreTags->isChecked());
+ if (ui->leHTMLCssPrefix->text().size())
+ generator->setHTMLClassName(ui->leHTMLCssPrefix->text().toStdString());
+
+ generator->setLATEXReplaceQuotes(ui->cbLATEXEscQuotes->isChecked());
+ generator->setLATEXNoShorthands(ui->cbLATEXBabel->isChecked());
+ generator->setLATEXPrettySymbols(ui->cbLATEXPrettySymbols->isChecked());
+
+ generator->setRTFPageSize(ui->comboRTFPageSize->currentText().toLower().toStdString());
+ generator->setRTFCharStyles(ui->cbRTFCharStyles->isChecked());
+
+ generator->setSVGSize(ui->leSVGWidth->text().toStdString(), ui->leSVGHeight->text().toStdString());
+ }
+
+ generator->setPrintLineNumbers( ui->cbIncLineNo->isChecked());
+ generator->setPrintZeroes(ui->cbPadZeroes->isEnabled() && ui->cbPadZeroes->isChecked());
+
+#ifdef DATA_DIR
+ QString themePath = QString("%1/themes/%2.style").arg(
+ DATA_DIR).arg(ui->comboTheme->currentText());
+#else
+ QString themePath = QString("%1/themes/%2.style").arg(
+ QDir::currentPath()).arg(ui->comboTheme->currentText());
+#endif
+
+ generator->initTheme(themePath.toStdString());
+
+ if (ui->cbEncoding->isChecked()) {
+ generator->setEncoding(ui->comboEncoding->currentText().toStdString());
+ } else {
+ generator->setEncoding("none");
+ }
+ generator->setValidateInput(ui->cbValidateInput->isChecked());
+ generator->setLineNumberWidth(ui->sbLineNoWidth->value());
+
+ if (getOutputType()!=highlight::LATEX && getOutputType()!=highlight::TEX){
+ string fntName=ui->comboFontName->currentText().toStdString();
+ if(fntName.size()) generator->setBaseFont(fntName);
+ string fntSize=ui->leFontSize->text().toStdString();
+ if(fntSize.size()) generator->setBaseFontSize(fntSize);
+ }
+
+ int lineLength = 0;
+ if (ui->cbWrapping->isChecked()){
+ lineLength = ( ui->cbIncLineNo->isChecked()
+ && ui->sbLineNoWidth->value() > ui->sbLineLength->value())?
+ ui->sbLineLength->value() - ui->sbLineNoWidth->value()
+ : ui->sbLineLength->value();
+ }
+ generator->setPreformatting(getWrappingStyle(), lineLength, ui->sbTabWidth->value());
+
+ if(ui->cbKwCase->isChecked()){
+ StringTools::KeywordCase kwCase=StringTools::CASE_UNCHANGED;
+ switch (ui->comboKwCase->currentIndex()){
+ case 0: kwCase=StringTools::CASE_UPPER; break;
+ case 1: kwCase=StringTools::CASE_LOWER; break;
+ case 2: kwCase=StringTools::CASE_CAPITALIZE; break;
+ }
+ generator->setKeyWordCase(kwCase);
+ }
+
+ if (ui->cbReformat->isChecked()){
+ generator->initIndentationScheme(ui->comboReformat->currentText().toLower().toStdString());
+
+ }
+
+ if ( ui->cbHTMLCtags->isChecked() && !ui->leHTMLCtagsFile->text().isEmpty()
+ && (outType==highlight::HTML || outType==highlight::XHTML)){
+ if (!generator->initTagInformation(ui->leHTMLCtagsFile->text().toStdString())){
+ QMessageBox::warning(this, tr("Tags file error"),
+ tr("Could not read tags information in \"%1\"").arg(ui->leHTMLCtagsFile->text()));
+ }
+ }
+}
+
+highlight::WrapMode MainWindow::getWrappingStyle(){
+ if (!ui->cbAdvWrapping->isChecked() && ui->cbAdvWrapping->isEnabled())
+ return highlight::WRAP_SIMPLE;
+ return (ui->cbWrapping->isChecked())?highlight::WRAP_DEFAULT:highlight::WRAP_DISABLED;
+}
+
+
+void MainWindow::on_pbStartConversion_clicked(){
+
+ if (!ui->lvInputFiles->count()) return;
+
+ if (!ui->cbWrite2Src->isChecked() && !QDir(ui->leOutputDest->text()).exists()){
+ QMessageBox::warning(this, tr("Output error"), tr("Output directory does not exist!"));
+ ui->leOutputDest->setFocus();
+ return;
+ }
+ highlight::OutputType outType = getOutputType();
+ QCheckBox* cbEmbed=NULL;
+ QLineEdit* leStyleFile=NULL;
+
+ if ( outType==highlight::HTML || outType==highlight::XHTML) {
+ cbEmbed = ui->cbHTMLEmbedStyle;
+ leStyleFile = ui->leHTMLStyleFile;
+ }
+ else if ( outType==highlight::LATEX ) {
+ cbEmbed = ui->cbLATEXEmbedStyle;
+ leStyleFile = ui->leLATEXStyleFile;
+ }
+ else if (outType==highlight::TEX ) {
+ cbEmbed = ui->cbTEXEmbedStyle;
+ leStyleFile = ui->leTEXStyleFile;
+ } else if (outType==highlight::SVG ) {
+ cbEmbed = ui->cbSVGEmbedStyle;
+ leStyleFile = ui->leSVGStyleFile;
+ }
+
+ if (cbEmbed && leStyleFile ) {
+ if ( !cbEmbed->isChecked() && leStyleFile->text().isEmpty()){
+ ui->tabWidget->setCurrentIndex(1);
+ if ( outType==highlight::HTML || outType==highlight::XHTML){
+ ui->tabWidget->setCurrentIndex(0);
+ }
+ leStyleFile->setFocus();
+ QMessageBox::warning(this, tr("Output error"), tr("You must define a style output file!"));
+ return;
+ }
+ }
+ ui->pbStartConversion->setDisabled(true);
+ ui->pbCopyFile2CP->setDisabled(true);
+ this->setCursor(Qt::WaitCursor);
+
+ QTime t;
+ t.start();
+
+ auto_ptr<highlight::CodeGenerator> generator(highlight::CodeGenerator::getInstance(outType));
+
+ applyCtrlValues(generator.get(), false);
+ string currentFile, suffix;
+ string outfileName;
+ string outfileSuffix = getOutFileSuffix().toStdString();
+ QString langDefPath;
+ QString inFileName, inFilePath;
+ highlight::ParseError error;
+ highlight::LoadResult loadRes;
+ QStringList inputErrors, outputErrors, reformatErrors;
+
+ for (int i=0; i<ui->lvInputFiles->count(); i++){
+ inFilePath = ui->lvInputFiles->item(i)->text();
+ currentFile = inFilePath.toStdString();
+ suffix = getFileType(getFileSuffix(currentFile), currentFile);
+#ifdef DATA_DIR
+ langDefPath = QDir::toNativeSeparators(QString("%1/langDefs/%2.lang").arg(DATA_DIR).arg(QString::fromStdString(suffix)));
+#else
+ langDefPath = QDir::toNativeSeparators(QString("%1/langDefs/%2.lang").arg(QDir::currentPath()).arg(QString::fromStdString(suffix)));
+#endif
+
+ loadRes=generator->initLanguage(langDefPath.toStdString());
+ if (loadRes==highlight::LOAD_FAILED_REGEX){
+ QMessageBox::warning(this, tr("Language definition error"),
+ tr("Invalid regular expression in %1:\n%2").arg(langDefPath).arg(
+ QString::fromStdString( generator->getLanguage().getFailedRegex())));
+ break;
+ } else if (loadRes==highlight::LOAD_FAILED) {
+ QMessageBox::warning(this, tr("Unknown syntax"), tr("Could not convert %1").arg(QString::fromStdString(currentFile)));
+ inputErrors.append(inFilePath);
+ } else {
+
+ if (ui->cbReformat->isChecked()&& !generator->formattingIsPossible()){
+ reformatErrors.append(inFilePath);
+ }
+
+ if (ui->cbWrite2Src->isChecked()) {
+ outfileName = currentFile;
+ } else {
+ QFileInfo outFileInfo;
+ outFileInfo.setFile(ui->leOutputDest->text(), QFileInfo(inFilePath).fileName());
+ outfileName = outFileInfo.absoluteFilePath().toStdString();
+ }
+ outfileName += outfileSuffix;
+
+ inFileName = QFileInfo(inFilePath).fileName();
+ if (ui->cbHTMLFileNameAnchor->isChecked()){
+ generator->setHTMLAnchorPrefix(inFileName.toStdString());
+ }
+ generator->setTitle(inFileName.toStdString());
+ error = generator->generateFile(currentFile,
+ outfileName );
+ if (error != highlight::PARSE_OK){
+ if (error == highlight::BAD_INPUT) {
+ inputErrors.append(inFilePath);
+ }
+ else {
+ outputErrors.append(inFilePath);
+ }
+ }
+ ui->progressBar->setValue(100*i / ui->lvInputFiles->count());
+ }
+ }
+
+ // write external Stylesheet
+ if (cbEmbed && leStyleFile && !cbEmbed->isChecked()) {
+ QString stylePath=QFileInfo(ui->leOutputDest->text(), leStyleFile->text()).absoluteFilePath();
+ bool styleFileOK=generator -> printExternalStyle(QDir::toNativeSeparators(stylePath).toStdString());
+ if (!styleFileOK) {
+ outputErrors.append(stylePath);
+ }
+ }
+
+ // write HTML index file
+ if ( (outType==highlight::HTML || outType==highlight::XHTML)
+ && ui->cbHTMLIndex->isChecked() && !ui->cbWrite2Src->isChecked()) {
+ vector <string> fileList;
+ for (int i=0;i<ui->lvInputFiles->count();i++){
+ fileList.push_back(QDir::toNativeSeparators(ui->lvInputFiles->item(i)->text()).toStdString());
+ }
+ QString outPath = QDir::toNativeSeparators(ui->leOutputDest->text());
+ if (!outPath.endsWith(QDir::separator())) outPath.append(QDir::separator());
+ bool indexFileOK=generator->printIndexFile(fileList, outPath.toStdString());
+ if (!indexFileOK) {
+ outputErrors.append(outPath+ ((outType==highlight::HTML)?"index.html":"index.xhtml"));
+ }
+ }
+
+ statusBar()->showMessage(tr("Converted %1 files in %2 ms").arg(ui->lvInputFiles->count()).arg(t.elapsed()));
+ ui->progressBar->reset();
+ this->setCursor(Qt::ArrowCursor);
+ ui->pbStartConversion->setEnabled(true);
+ ui->pbCopyFile2CP->setEnabled(true);
+
+ if (!inputErrors.isEmpty() || !outputErrors.isEmpty() || !reformatErrors.isEmpty()){
+ io_report report;
+ report.addInputErrors(inputErrors);
+ report.addOutputErrors(outputErrors);
+ report.addReformatErrors(reformatErrors);
+ report.exec();
+ if (report.removeInputErrorFiles()){
+ QList<QListWidgetItem*> items;
+ for (int i=0;i<inputErrors.count();i++){
+ items=ui->lvInputFiles->findItems(inputErrors.at(i),Qt::MatchExactly);
+ for (int j=0;j<items.count();j++){
+ delete items.at(j);
+ }
+ }
+ }
+ }
+}
+
+void MainWindow::on_pbCopyFile2CP_clicked(){
+
+ highlight2Clipboard(false);
+}
+
+void MainWindow::highlight2Clipboard(bool getDataFromCP){
+
+ if ((!getDataFromCP &&NULL==ui->lvInputFiles->currentItem())
+ || (getDataFromCP && savedClipboardContent.isEmpty())) return;
+
+ this->setCursor(Qt::WaitCursor);
+
+ auto_ptr<highlight::CodeGenerator> generator(
+ highlight::CodeGenerator::getInstance(getOutputType()));
+
+ applyCtrlValues(generator.get(), false);
+
+ string suffix;
+ if (getDataFromCP){
+ suffix= getFileType((ui->comboSelectSyntax->itemData(ui->comboSelectSyntax->currentIndex())).toString().toStdString(),"");
+ }else {
+ string currentFile = ui->lvInputFiles->currentItem()->text().toStdString();
+ suffix = getFileType(getFileSuffix(currentFile), currentFile);
+
+ QString inFileName = QFileInfo(ui->lvInputFiles->currentItem()->text()).fileName();
+ generator->setTitle(inFileName.toStdString());
+ }
+
+#ifdef DATA_DIR
+ QString langPath = QDir::toNativeSeparators(QString("%1/langDefs/%2.lang").arg(
+ DATA_DIR).arg(QString::fromStdString(suffix)));
+#else
+ QString langPath = QDir::toNativeSeparators(QString("%1/langDefs/%2.lang").arg(
+ QDir::currentPath()).arg(QString::fromStdString(suffix)));
+#endif
+
+ if ( generator->initLanguage(langPath.toStdString()) != highlight::LOAD_FAILED){
+ QString clipBoardData;
+ if (getDataFromCP){
+ clipBoardData= QString::fromStdString( generator->generateString(savedClipboardContent.toStdString()));
+ } else {
+ clipBoardData= QString::fromStdString( generator->generateStringFromFile(ui->lvInputFiles->currentItem()->text().toStdString()));
+ }
+
+ QClipboard *clipboard = QApplication::clipboard();
+ if (clipboard) {
+ highlight::OutputType outputType = getOutputType();
+ if ( outputType==highlight::RTF){
+ QMimeData *mimeData = new QMimeData();
+#ifdef WIN32
+ mimeData->setData("Rich Text Format", clipBoardData.toAscii());
+#else
+ mimeData->setData("text/rtf", clipBoardData.toAscii());
+#endif
+ clipboard->setMimeData(mimeData);
+ } else {
+ clipboard->setText(clipBoardData);
+ }
+ }
+ } else {
+ statusBar()->showMessage(
+ tr("Conversion of \"%1\" not possible.").arg((getDataFromCP)?tr("clipboard data"):ui->lvInputFiles->currentItem()->text()));
+ }
+ this->setCursor(Qt::ArrowCursor);
+}
+
+ void MainWindow::plausibility(){
+ ui->leOutputDest->setEnabled(!ui->cbWrite2Src->isChecked());
+ ui->pbOutputDest->setEnabled(!ui->cbWrite2Src->isChecked());
+ ui->pbOutputDest->setEnabled(!ui->cbWrite2Src->isChecked());
+ ui->leOutputDest->setEnabled(!ui->cbWrite2Src->isChecked());
+ ui->cbPadZeroes->setEnabled(ui->cbIncLineNo->isChecked());
+ ui->cbAdvWrapping->setEnabled(ui->cbWrapping->isChecked());
+ ui->comboEncoding->setEnabled(ui->cbEncoding->isChecked());
+
+ ui->comboReformat->setEnabled(ui->cbReformat->isChecked());
+ ui->comboKwCase->setEnabled(ui->cbKwCase->isChecked());
+ ui->cbHTMLInlineCSS->setEnabled(ui->cbHTMLEmbedStyle->isChecked());
+ ui->cbHTMLFileNameAnchor->setEnabled(ui->cbHTMLAnchors->isChecked());
+ ui->leHTMLStyleFile->setEnabled(!ui->cbHTMLEmbedStyle->isChecked());
+ ui->leHTMLStyleIncFile->setEnabled(ui->cbHTMLEmbedStyle->isChecked() && !ui->cbHTMLInlineCSS->isChecked());
+ ui->pbHTMLChooseStyleIncFile->setEnabled(ui->cbHTMLEmbedStyle->isChecked() &&!ui->cbHTMLInlineCSS->isChecked());
+ ui->leHTMLCssPrefix->setEnabled(!ui->cbHTMLInlineCSS->isChecked());
+ ui->leHTMLCtagsFile->setEnabled(ui->cbHTMLCtags->isChecked());
+ ui->pbHTMLChooseTagsFile->setEnabled(ui->cbHTMLCtags->isChecked());
+ ui->leLATEXStyleFile->setEnabled(!ui->cbLATEXEmbedStyle->isChecked());
+ ui->leTEXStyleFile->setEnabled(!ui->cbTEXEmbedStyle->isChecked());
+ ui->leSVGStyleFile->setEnabled(!ui->cbSVGEmbedStyle->isChecked());
+ ui->cbFragment->setEnabled( getOutputType()!=highlight::RTF && getOutputType()!=highlight::SVG );
+ ui->sbLineNoWidth->setEnabled(ui->cbIncLineNo->isChecked());
+ ui->cbHTMLIndex->setEnabled(!ui->cbWrite2Src->isChecked());
+ ui->cbHTMLEnclosePreTags->setEnabled(ui->cbFragment->isChecked());
+ ui->cbHTMLAnchors->setEnabled(ui->cbIncLineNo->isChecked());
+ ui->cbHTMLFileNameAnchor->setEnabled(ui->cbIncLineNo->isChecked());
+ ui->cbHTMLOrderedList->setEnabled(ui->cbIncLineNo->isChecked());
+
+ ui->pbCopyToCP->setEnabled(!savedClipboardContent.isEmpty());
+
+ switch (ui->comboFormat->currentIndex()) {
+ case 0:
+ case 1:
+ ui->stackedSpecificOptions->setCurrentIndex(0);
+ break;
+ case 2:
+ ui->stackedSpecificOptions->setCurrentIndex(1);
+ break;
+ case 3:
+ ui->stackedSpecificOptions->setCurrentIndex(2);
+ break;
+ case 4:
+ ui->stackedSpecificOptions->setCurrentIndex(3);
+ break;
+ case 5:
+ ui->stackedSpecificOptions->setCurrentIndex(4);
+ break;
+ default:
+ ui->stackedSpecificOptions->setCurrentIndex(5);
+ break;
+ }
+ }
+
+ void MainWindow::updatePreview() {
+
+ // is clipboard tab chosen?
+ bool getDataFromCP = ui->tabIOSelection->currentIndex()==1;
+
+ if ((!getDataFromCP && NULL==ui->lvInputFiles->currentItem())
+ || (getDataFromCP && savedClipboardContent.isEmpty())) return;
+
+ int vScroll = ui->browserPreview->verticalScrollBar()->value();
+ int hScroll = ui->browserPreview->horizontalScrollBar()->value();
+ this->setCursor(Qt::WaitCursor);
+ highlight::HtmlGenerator pwgenerator;
+ pwgenerator.setIncludeStyle(true);
+ pwgenerator.setHTMLInlineCSS(true);
+ if (!getDataFromCP){
+ pwgenerator.setMaxInputLineCnt(500);
+ }
+
+ applyCtrlValues(&pwgenerator, true);
+
+ string suffix;
+
+ if (getDataFromCP){
+ suffix= getFileType((ui->comboSelectSyntax->itemData(ui->comboSelectSyntax->currentIndex())).toString().toStdString(),"");
+ } else {
+ string currentFile = ui->lvInputFiles->currentItem()->text().toStdString();
+ suffix = getFileType(getFileSuffix(currentFile), currentFile);
+ }
+#ifdef DATA_DIR
+ QString langPath = QDir::toNativeSeparators(QString("%1/langDefs/%2.lang").arg(
+ DATA_DIR).arg(QString::fromStdString(suffix)));
+#else
+ QString langPath = QDir::toNativeSeparators(QString("%1/langDefs/%2.lang").arg(
+ QDir::currentPath()).arg(QString::fromStdString(suffix)));
+#endif
+
+
+ if ( pwgenerator.initLanguage(langPath.toStdString()) != highlight::LOAD_FAILED){
+
+ ui->lbPreview->setText(tr("Preview (%1):").arg(
+ (getDataFromCP)?tr("clipboard data"):ui->lvInputFiles->currentItem()->text()) );
+
+ statusBar()->showMessage(tr("Current syntax: %1").arg( QString::fromStdString(pwgenerator.getLanguage().getDescription())));
+ QString previewData;
+
+ // fix utf-8 data preview - to be improved (other encodings??)
+ if (ui->cbEncoding->isChecked() && ui->comboEncoding->currentText().toLower()=="utf-8"){
+ if (getDataFromCP){
+ previewData= QString::fromUtf8( pwgenerator.generateString(savedClipboardContent.toStdString()).c_str());
+ } else {
+ previewData= QString::fromUtf8( pwgenerator.generateStringFromFile(ui->lvInputFiles->currentItem()->text().toStdString()).c_str());
+ }
+ }
+ else {
+ if (getDataFromCP){
+ previewData= QString::fromStdString( pwgenerator.generateString(savedClipboardContent.toStdString()));
+ } else {
+ previewData= QString::fromStdString( pwgenerator.generateStringFromFile(ui->lvInputFiles->currentItem()->text().toStdString()));
+ }
+ }
+
+ ui->browserPreview->setHtml(previewData);
+ } else {
+ statusBar()->showMessage(tr("Preview of \"%1\" not possible.").arg((getDataFromCP)?tr("clipboard data"):ui->lvInputFiles->currentItem()->text()));
+ }
+ ui->browserPreview->verticalScrollBar()->setValue(vScroll);
+ ui->browserPreview->horizontalScrollBar()->setValue(hScroll);
+ this->setCursor(Qt::ArrowCursor);
+ }
+
+
+
+void MainWindow::on_pbHTMLChooseTagsFile_clicked()
+{
+ selectSingleFile(ui->leHTMLCtagsFile, tr("Choose a ctags file"), "*");
+}
+
+void MainWindow::on_action_Manual_triggered()
+{
+ ShowTextFile show;
+ show.setFileName("README");
+ show.exec();
+}
+
+void MainWindow::on_action_Changelog_triggered()
+{
+ ShowTextFile show;
+ show.setFileName("ChangeLog");
+ show.exec();
+}
+
+void MainWindow::on_action_License_triggered()
+{
+ ShowTextFile show;
+ show.setFileName("COPYING");
+ show.exec();
+}
+
+void MainWindow::on_pbHTMLChooseStyleIncFile_clicked()
+{
+ selectSingleFile(ui->leHTMLStyleIncFile, tr("Choose a style include file"), "*.css");
+}
+void MainWindow::on_pbSVGChooseStyleIncFile_clicked()
+{
+ selectSingleFile(ui->leSVGStyleIncFile, tr("Choose a style include file"), "*.css");
+}
+void MainWindow::on_pbLATEXChooseStyleIncFile_clicked()
+{
+ selectSingleFile(ui->leLATEXStyleIncFile, tr("Choose a style include file"), "*.sty");
+}
+
+void MainWindow::on_pbTEXChooseStyleIncFile_clicked()
+{
+ selectSingleFile(ui->leTEXStyleIncFile, tr("Choose a style include file"), "*.sty");
+}
+
+
+void MainWindow::on_actionAbout_translations_triggered()
+{
+ QMessageBox::information(this, tr("About providing translations"),
+ tr("The GUI was developed using the Qt toolkit, and "
+ "translations may be provided using the tools Qt Linguist and lrelease.\n"
+ "The highlight.ts file for Linguist resides in the src/gui-qt subdirectory.\n"
+ "The qm file generated by lrelease has to be saved in gui-files/l10n.\n\n"
+ "Please send a note to as (at) andre-simon (dot) de if you have issues during translating "
+ "or if you have finished or updated a translation."));
+}
+
+ void MainWindow::dropEvent(QDropEvent *event)
+ {
+ const QMimeData *mimeData = event->mimeData();
+
+ if (mimeData && mimeData->hasUrls()) {
+ QList<QUrl> urlList = mimeData->urls();
+ QString url;
+ for (int i = 0; i < urlList.size(); ++i) {
+ url=urlList.at(i).toLocalFile();
+ if (ui->lvInputFiles->findItems ( url, Qt::MatchExactly ).empty()) {
+ ui->lvInputFiles->addItem(url);
+ }
+ }
+ }
+ event->acceptProposedAction();
+ }
+
+ void MainWindow::dragEnterEvent(QDragEnterEvent *event)
+ {
+ event->acceptProposedAction();
+ }
+
+ void MainWindow::dragMoveEvent(QDragMoveEvent *event)
+ {
+ event->acceptProposedAction();
+ }
+
+ void MainWindow::dragLeaveEvent(QDragLeaveEvent *event)
+ {
+ event->accept();
+ }
+
+void MainWindow::on_pbPasteFromCB_clicked()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ if (clipboard) {
+ savedClipboardContent = clipboard->text();
+ updatePreview();
+ ui->pbCopyToCP->setEnabled(!savedClipboardContent.isEmpty());
+ }
+
+}
+
+void MainWindow::on_pbCopyToCP_clicked()
+{
+ highlight2Clipboard(true);
+}
diff --git a/support/highlight/src/gui-qt/mainwindow.h b/support/highlight/src/gui-qt/mainwindow.h
new file mode 100644
index 0000000000..89c181168a
--- /dev/null
+++ b/support/highlight/src/gui-qt/mainwindow.h
@@ -0,0 +1,123 @@
+/***************************************************************************
+ mainwindow.h
+ -------------------
+ begin : Mo 16.03.2009
+ copyright : (C) 2009 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtGui/QMainWindow>
+#include <QtGui/QMessageBox>
+#include <QtGui/QFileDialog>
+#include <QSettings>
+#include <QDir>
+#include <QClipboard>
+#include <QMimeData>
+#include <QTime>
+#include <QLineEdit>
+#include <QString>
+#include <QTextStream>
+#include <QScrollBar>
+#include <QDropEvent>
+
+#include "version.h"
+#include "codegenerator.h"
+#include "htmlgenerator.h"
+#include "configurationreader.h"
+
+#include "enums.h"
+
+typedef map<string, string> StringMap;
+
+namespace Ui
+{
+ class MainWindowClass;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+ void addInputFiles(const QStringList& list);
+
+private:
+ Ui::MainWindowClass *ui;
+ StringMap extensions, shebangs;
+ QString fileOpenFilter;
+ QString savedClipboardContent;
+
+ void readSettings();
+ void writeSettings();
+ highlight::OutputType getOutputType();
+ highlight::WrapMode getWrappingStyle();
+ QString getOutFileSuffix();
+ void applyCtrlValues(highlight::CodeGenerator* generator, bool previewMode);
+ void selectSingleFile(QLineEdit*, const QString&, const QString&);
+ bool loadFileTypeConfig(StringMap* extMap, StringMap* shebangMap);
+ void highlight2Clipboard(bool getDataFromCP);
+
+ string analyzeFile(const string& file);
+ string getFileType(const string& suffix, const string &inputFile);
+ string getFileSuffix(const string& fileName);
+
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dropEvent(QDropEvent *event);
+
+public slots:
+ //This is a slot like the ones we used in our last tutorial
+ // The difference here that it gets automatically connect
+ // If you use on_objectname_signalname it's like connect(pushButton,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()))
+
+ void on_pbClearSelection_clicked();
+ void on_pbOutputDest_clicked();
+ void on_pbStartConversion_clicked();
+ void on_pbCopyFile2CP_clicked();
+
+private slots:
+
+ void on_pbCopyToCP_clicked();
+ void on_pbPasteFromCB_clicked();
+ void on_actionAbout_translations_triggered();
+ void on_pbTEXChooseStyleIncFile_clicked();
+ void on_pbLATEXChooseStyleIncFile_clicked();
+ void on_pbHTMLChooseStyleIncFile_clicked();
+ void on_pbSVGChooseStyleIncFile_clicked();
+ void on_action_License_triggered();
+ void on_action_Changelog_triggered();
+ void on_action_Manual_triggered();
+ void on_pbHTMLChooseTagsFile_clicked();
+ void on_action_About_Highlight_triggered();
+ void on_action_Exit_triggered();
+ void plausibility();
+ void updatePreview();
+ void openFiles();
+
+};
+
+#endif // MAINWINDOW_H
diff --git a/support/highlight/src/gui-qt/mainwindow.ui b/support/highlight/src/gui-qt/mainwindow.ui
new file mode 100644
index 0000000000..0bb46f6216
--- /dev/null
+++ b/support/highlight/src/gui-qt/mainwindow.ui
@@ -0,0 +1,2147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindowClass</class>
+ <widget class="QMainWindow" name="MainWindowClass">
+ <property name="windowModality">
+ <enum>Qt::ApplicationModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>645</height>
+ </rect>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="windowTitle">
+ <string>Highlight</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="highlight-gui.qrc">
+ <normaloff>:/hl_icon2.png</normaloff>:/hl_icon2.png</iconset>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QHBoxLayout" name="horizontalLayout_24">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_7">
+ <item>
+ <widget class="QTabWidget" name="tabIOSelection">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <widget class="QWidget" name="tab_file_io">
+ <attribute name="title">
+ <string>Files</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QPushButton" name="pbOpenFiles">
+ <property name="toolTip">
+ <string>Choose the source code files you want to convert.</string>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>Choose input files</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="lvInputFiles">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>List of input files.</string>
+ </property>
+ <property name="dragDropMode">
+ <enum>QAbstractItemView::DropOnly</enum>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="pbClearSelection">
+ <property name="toolTip">
+ <string>Remove the selected input files.</string>
+ </property>
+ <property name="text">
+ <string>Clear selection</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbClearAll">
+ <property name="toolTip">
+ <string>Remove all input files.</string>
+ </property>
+ <property name="text">
+ <string>Clear all</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line_11">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label_11">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Output destination:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_22">
+ <item>
+ <widget class="QLineEdit" name="leOutputDest">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Output directory</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbOutputDest">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Select the output directory.</string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbWrite2Src">
+ <property name="toolTip">
+ <string>Save output in the input file directories.</string>
+ </property>
+ <property name="text">
+ <string>Write to source directories</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbStartConversion">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>120</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <family>MS Shell Dlg 2</family>
+ <pointsize>10</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>Start the conversion of your input files.</string>
+ </property>
+ <property name="text">
+ <string>Convert files</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbCopyFile2CP">
+ <property name="toolTip">
+ <string>Copy highlighted code of the seleted file into the clipboard.</string>
+ </property>
+ <property name="text">
+ <string>Copy file to clipboard</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_clipboard">
+ <attribute name="title">
+ <string>Clipboard</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_15">
+ <item>
+ <widget class="QPushButton" name="pbPasteFromCB">
+ <property name="toolTip">
+ <string>Paste clipboard content into the preview window.</string>
+ </property>
+ <property name="text">
+ <string>Paste from clipboard</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_23">
+ <item>
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>Select syntax:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboSelectSyntax">
+ <property name="toolTip">
+ <string>Select the correct syntax of the code snippet.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line_14">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbCopyToCP">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>Copy highlighted code into the clipboard.</string>
+ </property>
+ <property name="text">
+ <string>Copy preview to clipboard</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_12">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>106</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_7">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="tabPosition">
+ <enum>QTabWidget::North</enum>
+ </property>
+ <property name="tabShape">
+ <enum>QTabWidget::Rounded</enum>
+ </property>
+ <property name="currentIndex">
+ <number>2</number>
+ </property>
+ <widget class="QWidget" name="page_general">
+ <attribute name="title">
+ <string>General</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Output format:</string>
+ </property>
+ <property name="buddy">
+ <cstring>comboFormat</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboFormat">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>Choose an output format.</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>HTML</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>XHTML</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>LaTeX</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>TeX</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RTF</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SVG</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>XML</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BBCode</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line_9">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_21">
+ <item>
+ <widget class="QCheckBox" name="cbIncLineNo">
+ <property name="toolTip">
+ <string>Add line numbers to the output.</string>
+ </property>
+ <property name="text">
+ <string>Add line numbers</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>10</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sbLineNoWidth">
+ <property name="toolTip">
+ <string>Select the line number width.</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>6</number>
+ </property>
+ <property name="value">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbPadZeroes">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Fill leading space of line numbers with zeroes.</string>
+ </property>
+ <property name="text">
+ <string>Pad with zeroes</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbFragment">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Generate output without document header and footer.</string>
+ </property>
+ <property name="text">
+ <string>Omit header and footer</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbValidateInput">
+ <property name="toolTip">
+ <string>Test if input data is not binary.
+Removes Unicode BOM mark.</string>
+ </property>
+ <property name="text">
+ <string>Validate input data</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="cbEncoding">
+ <property name="toolTip">
+ <string>Set the output file ancoding.</string>
+ </property>
+ <property name="text">
+ <string>Set encoding:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboEncoding">
+ <property name="toolTip">
+ <string>Select or define the encoding.
+The result has to match the input file encoding.</string>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <property name="insertPolicy">
+ <enum>QComboBox::InsertAtBottom</enum>
+ </property>
+ <item>
+ <property name="text">
+ <string>ISO-8859-1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-2</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-3</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-6</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-7</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-8</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-9</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-10</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-11</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-12</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-13</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ISO-8859-15</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>UTF-8</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_output_spec">
+ <attribute name="title">
+ <string>Output specific</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QStackedWidget" name="stackedSpecificOptions">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="HTMLOptions">
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QLabel" name="label_17">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>HTML options</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_12">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>250</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tabWidgetPage1">
+ <attribute name="title">
+ <string>Stylesheets</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_10">
+ <item>
+ <widget class="QCheckBox" name="cbHTMLEmbedStyle">
+ <property name="toolTip">
+ <string>Include the style information in each output file.</string>
+ </property>
+ <property name="text">
+ <string>Embed style (CSS)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbHTMLInlineCSS">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Add CSS information to each tag (do not use CSS class definitions).</string>
+ </property>
+ <property name="text">
+ <string>Inline CSS</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_14">
+ <item>
+ <widget class="QLabel" name="label_19">
+ <property name="text">
+ <string>Stylesheet file:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="leHTMLStyleFile">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Name of the referenced style file.</string>
+ </property>
+ <property name="text">
+ <string>highlight.css</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_9">
+ <item>
+ <widget class="QLabel" name="label_20">
+ <property name="text">
+ <string>Include:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="leHTMLStyleIncFile">
+ <property name="toolTip">
+ <string>Path of the CSS include file.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbHTMLChooseStyleIncFile">
+ <property name="toolTip">
+ <string>Select a CSS include file.</string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>CSS class prefix:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="leHTMLCssPrefix">
+ <property name="toolTip">
+ <string>Add a CSS class name prefix to avoid namespace clashes.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="0">
+ <spacer name="verticalSpacer_9">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabWidgetPage2">
+ <attribute name="title">
+ <string>Index/ctags</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_6">
+ <item>
+ <widget class="QCheckBox" name="cbHTMLIndex">
+ <property name="toolTip">
+ <string>Generate an index file with hyperlinks to all outputted files.</string>
+ </property>
+ <property name="text">
+ <string>Generate index file</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_13">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbHTMLCtags">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Read a ctags file and add the included metainformation as tooltips.
+See ctags.sf.net for details.</string>
+ </property>
+ <property name="text">
+ <string>Read ctags file:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_12">
+ <item>
+ <widget class="QLineEdit" name="leHTMLCtagsFile">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Path of the ctags file.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbHTMLChooseTagsFile">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Choose a ctags file.</string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_8">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>72</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabWidgetPage3">
+ <attribute name="title">
+ <string>Misc</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_8">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Line numbering options:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbHTMLAnchors">
+ <property name="toolTip">
+ <string>Add an achor to each line.</string>
+ </property>
+ <property name="text">
+ <string>Add line anchors</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbHTMLFileNameAnchor">
+ <property name="toolTip">
+ <string>Add the filename as prefix to the anchors.</string>
+ </property>
+ <property name="text">
+ <string>Include file name in anchor</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbHTMLOrderedList">
+ <property name="toolTip">
+ <string>Output the lines within an ordered list.</string>
+ </property>
+ <property name="text">
+ <string>Output as ordered list</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbHTMLEnclosePreTags">
+ <property name="toolTip">
+ <string>Add &amp;lt;pre&amp;gt; tags to the output, if the flag &quot;No document header and footer&quot; is selected.</string>
+ </property>
+ <property name="text">
+ <string>Enclose in pre tags</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>24</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="LATEXOptions">
+ <layout class="QVBoxLayout" name="verticalLayout_12">
+ <item>
+ <widget class="QLabel" name="label_18">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>LaTeX options</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_8">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbLATEXEscQuotes">
+ <property name="toolTip">
+ <string>Replace quotes by dq sequences.</string>
+ </property>
+ <property name="text">
+ <string>Escape quotes</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbLATEXBabel">
+ <property name="toolTip">
+ <string>Make output Babel compatible.</string>
+ </property>
+ <property name="text">
+ <string>Add Babel compatibility</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbLATEXPrettySymbols">
+ <property name="toolTip">
+ <string>Replace default symbols (brackets, tilde) by nice redefinitions.</string>
+ </property>
+ <property name="text">
+ <string>Add pretty symbols</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbLATEXEmbedStyle">
+ <property name="toolTip">
+ <string>Include the style information in each output file.</string>
+ </property>
+ <property name="text">
+ <string>Embed style (defs)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_17">
+ <item>
+ <widget class="QLabel" name="label_21">
+ <property name="text">
+ <string>Stylesheet file:</string>
+ </property>
+ <property name="buddy">
+ <cstring>leLATEXStyleFile</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="leLATEXStyleFile">
+ <property name="toolTip">
+ <string>Name of the referenced style file.</string>
+ </property>
+ <property name="text">
+ <string>highlight.sty</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_15">
+ <item>
+ <widget class="QLabel" name="label_22">
+ <property name="text">
+ <string>Stylesheet include file:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_16">
+ <item>
+ <widget class="QLineEdit" name="leLATEXStyleIncFile">
+ <property name="toolTip">
+ <string>Path of the style include file.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbLATEXChooseStyleIncFile">
+ <property name="toolTip">
+ <string>Select a style include file.</string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="TEXOptions">
+ <layout class="QVBoxLayout" name="verticalLayout_14">
+ <item>
+ <widget class="QLabel" name="label_26">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>TeX options</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_10">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbTEXEmbedStyle">
+ <property name="toolTip">
+ <string>Include the style information in each output file.</string>
+ </property>
+ <property name="text">
+ <string>Embed style (macros)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_18">
+ <item>
+ <widget class="QLabel" name="label_24">
+ <property name="text">
+ <string>Stylesheet file:</string>
+ </property>
+ <property name="buddy">
+ <cstring>leTEXStyleFile</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="leTEXStyleFile">
+ <property name="toolTip">
+ <string>Name of the referenced style file.</string>
+ </property>
+ <property name="text">
+ <string>highlight.sty</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_19">
+ <item>
+ <widget class="QLabel" name="label_25">
+ <property name="text">
+ <string>Stylesheet include file:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_20">
+ <item>
+ <widget class="QLineEdit" name="leTEXStyleIncFile">
+ <property name="toolTip">
+ <string>Path of the style include file.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbTEXChooseStyleIncFile">
+ <property name="toolTip">
+ <string>Select a style include file.</string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="RTFOptions">
+ <layout class="QVBoxLayout" name="verticalLayout_9">
+ <item>
+ <widget class="QLabel" name="label_15">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>RTF options</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbRTFCharStyles">
+ <property name="toolTip">
+ <string>Add character stylesheets with formatting information.
+You can select the stylesheets in your word processor to reformat additional text.</string>
+ </property>
+ <property name="text">
+ <string>Add character styles</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_11">
+ <item>
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>Page size:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboRTFPageSize">
+ <property name="toolTip">
+ <string>Select a page size.</string>
+ </property>
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>A3</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>A4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>A5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>B4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>B5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>B6</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Letter</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Legal</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="SVGOptions">
+ <layout class="QVBoxLayout" name="verticalLayout_10">
+ <item>
+ <widget class="QLabel" name="label_16">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>SVG options</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>Image size:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout_8">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Width:</string>
+ </property>
+ <property name="buddy">
+ <cstring>leSVGWidth</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="leSVGWidth">
+ <property name="toolTip">
+ <string>Enter the SVG width (may contain units).</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>Height:</string>
+ </property>
+ <property name="buddy">
+ <cstring>leSVGHeight</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="leSVGHeight">
+ <property name="toolTip">
+ <string>Enter the SVG height (may contain units).</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbSVGEmbedStyle">
+ <property name="toolTip">
+ <string>Include the style information in each output file.</string>
+ </property>
+ <property name="text">
+ <string>Embed style (CSS)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_26">
+ <item>
+ <widget class="QLabel" name="label_29">
+ <property name="text">
+ <string>Stylesheet file:</string>
+ </property>
+ <property name="buddy">
+ <cstring>leSVGStyleFile</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="leSVGStyleFile">
+ <property name="toolTip">
+ <string>Name of the referenced style file.</string>
+ </property>
+ <property name="text">
+ <string>highlight.css</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_27">
+ <item>
+ <widget class="QLabel" name="label_30">
+ <property name="text">
+ <string>Stylesheet include file:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_28">
+ <item>
+ <widget class="QLineEdit" name="leSVGStyleIncFile">
+ <property name="toolTip">
+ <string>Path of the CSS include file.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbSVGChooseStyleIncFile">
+ <property name="toolTip">
+ <string>Select a style include file.</string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_10">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="EmptyPage">
+ <layout class="QVBoxLayout" name="verticalLayout_11">
+ <item>
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>No options defined.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_formatting">
+ <attribute name="title">
+ <string>Formatting</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_8">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Color theme:</string>
+ </property>
+ <property name="buddy">
+ <cstring>comboTheme</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboTheme">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Select a colour theme.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QCheckBox" name="cbReformat">
+ <property name="toolTip">
+ <string>Reformat and indent your code.
+This feature is enabled tor C, C++, C# and Java code.</string>
+ </property>
+ <property name="text">
+ <string>Reformat:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboReformat">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Choose a formatting scheme.</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>Allman</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Banner</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>GNU</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Horstmann</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Java</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>K&amp;R</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Linux</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>OTBS</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Stroustrup</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Whitesmith</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QCheckBox" name="cbKwCase">
+ <property name="toolTip">
+ <string>Change the keyword case.</string>
+ </property>
+ <property name="text">
+ <string>Keyword case:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboKwCase">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Select a keyword case.</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>UPPER</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>lower</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Capitalize</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Tab width:</string>
+ </property>
+ <property name="buddy">
+ <cstring>sbTabWidth</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sbTabWidth">
+ <property name="toolTip">
+ <string>Enter the number of spaces which replace a tab.
+Set the width to 0 to keep tabs.</string>
+ </property>
+ <property name="maximum">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="cbWrapping">
+ <property name="toolTip">
+ <string>Enable line wrapping.</string>
+ </property>
+ <property name="text">
+ <string>Line wrapping</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="sbLineLength">
+ <property name="toolTip">
+ <string>Enter the maximum line length.</string>
+ </property>
+ <property name="minimum">
+ <number>60</number>
+ </property>
+ <property name="maximum">
+ <number>120</number>
+ </property>
+ <property name="singleStep">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="cbAdvWrapping">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Indent statements and function parameters after wrapping.</string>
+ </property>
+ <property name="text">
+ <string>Intelligent wrapping</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <spacer name="verticalSpacer_11">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>13</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout_9">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_23">
+ <property name="text">
+ <string>Font name:</string>
+ </property>
+ <property name="buddy">
+ <cstring>comboFontName</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QFontComboBox" name="comboFontName">
+ <property name="toolTip">
+ <string>Select or enter the font name.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Font size:</string>
+ </property>
+ <property name="buddy">
+ <cstring>leFontSize</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="leFontSize">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Enter the font size.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_13">
+ <item>
+ <widget class="QLabel" name="lbPreview">
+ <property name="text">
+ <string>Preview</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextBrowser" name="browserPreview">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_13">
+ <item>
+ <widget class="QLabel" name="label_14">
+ <property name="text">
+ <string>Output progress:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menuBar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menu_File">
+ <property name="title">
+ <string>&amp;File</string>
+ </property>
+ <addaction name="action_Open_files"/>
+ <addaction name="separator"/>
+ <addaction name="action_Exit"/>
+ </widget>
+ <widget class="QMenu" name="menu_Help">
+ <property name="title">
+ <string>&amp;Help</string>
+ </property>
+ <addaction name="action_Tips"/>
+ <addaction name="action_Manual"/>
+ <addaction name="action_Changelog"/>
+ <addaction name="action_License"/>
+ <addaction name="separator"/>
+ <addaction name="actionAbout_translations"/>
+ <addaction name="separator"/>
+ <addaction name="action_About_Highlight"/>
+ </widget>
+ <addaction name="menu_File"/>
+ <addaction name="menu_Help"/>
+ </widget>
+ <widget class="QStatusBar" name="statusBar"/>
+ <action name="action_Open_files">
+ <property name="text">
+ <string>&amp;Open files</string>
+ </property>
+ </action>
+ <action name="action_Exit">
+ <property name="text">
+ <string>&amp;Exit</string>
+ </property>
+ </action>
+ <action name="action_Load">
+ <property name="text">
+ <string>&amp;Load</string>
+ </property>
+ </action>
+ <action name="action_Save">
+ <property name="text">
+ <string>&amp;Save</string>
+ </property>
+ </action>
+ <action name="actionLoad_default_project">
+ <property name="text">
+ <string>Load &amp;default project</string>
+ </property>
+ </action>
+ <action name="action_Manual">
+ <property name="text">
+ <string>Readme</string>
+ </property>
+ </action>
+ <action name="action_Tips">
+ <property name="text">
+ <string>&amp;Tips</string>
+ </property>
+ <property name="visible">
+ <bool>false</bool>
+ </property>
+ </action>
+ <action name="action_Changelog">
+ <property name="text">
+ <string>&amp;Changelog</string>
+ </property>
+ </action>
+ <action name="action_License">
+ <property name="text">
+ <string>&amp;License</string>
+ </property>
+ </action>
+ <action name="action_About_Highlight">
+ <property name="text">
+ <string>&amp;About Highlight</string>
+ </property>
+ </action>
+ <action name="actionAbout_translations">
+ <property name="text">
+ <string>About &amp;translations</string>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <tabstops>
+ <tabstop>pbOpenFiles</tabstop>
+ <tabstop>lvInputFiles</tabstop>
+ <tabstop>pbClearSelection</tabstop>
+ <tabstop>pbClearAll</tabstop>
+ <tabstop>tabWidget</tabstop>
+ <tabstop>comboFormat</tabstop>
+ <tabstop>cbIncLineNo</tabstop>
+ <tabstop>sbLineNoWidth</tabstop>
+ <tabstop>cbPadZeroes</tabstop>
+ <tabstop>cbFragment</tabstop>
+ <tabstop>cbValidateInput</tabstop>
+ <tabstop>cbEncoding</tabstop>
+ <tabstop>comboEncoding</tabstop>
+ <tabstop>cbHTMLEmbedStyle</tabstop>
+ <tabstop>cbHTMLInlineCSS</tabstop>
+ <tabstop>leHTMLStyleFile</tabstop>
+ <tabstop>leHTMLStyleIncFile</tabstop>
+ <tabstop>pbHTMLChooseStyleIncFile</tabstop>
+ <tabstop>leHTMLCssPrefix</tabstop>
+ <tabstop>cbHTMLIndex</tabstop>
+ <tabstop>cbHTMLCtags</tabstop>
+ <tabstop>leHTMLCtagsFile</tabstop>
+ <tabstop>pbHTMLChooseTagsFile</tabstop>
+ <tabstop>cbHTMLAnchors</tabstop>
+ <tabstop>cbHTMLFileNameAnchor</tabstop>
+ <tabstop>cbHTMLOrderedList</tabstop>
+ <tabstop>cbHTMLEnclosePreTags</tabstop>
+ <tabstop>cbLATEXEscQuotes</tabstop>
+ <tabstop>cbLATEXBabel</tabstop>
+ <tabstop>cbLATEXPrettySymbols</tabstop>
+ <tabstop>cbLATEXEmbedStyle</tabstop>
+ <tabstop>leLATEXStyleFile</tabstop>
+ <tabstop>leLATEXStyleIncFile</tabstop>
+ <tabstop>pbLATEXChooseStyleIncFile</tabstop>
+ <tabstop>cbTEXEmbedStyle</tabstop>
+ <tabstop>leTEXStyleFile</tabstop>
+ <tabstop>leTEXStyleIncFile</tabstop>
+ <tabstop>pbTEXChooseStyleIncFile</tabstop>
+ <tabstop>cbRTFCharStyles</tabstop>
+ <tabstop>comboRTFPageSize</tabstop>
+ <tabstop>leSVGWidth</tabstop>
+ <tabstop>leSVGHeight</tabstop>
+ <tabstop>cbSVGEmbedStyle</tabstop>
+ <tabstop>leSVGStyleFile</tabstop>
+ <tabstop>leSVGStyleIncFile</tabstop>
+ <tabstop>pbSVGChooseStyleIncFile</tabstop>
+ <tabstop>comboTheme</tabstop>
+ <tabstop>cbReformat</tabstop>
+ <tabstop>comboReformat</tabstop>
+ <tabstop>cbKwCase</tabstop>
+ <tabstop>comboKwCase</tabstop>
+ <tabstop>sbTabWidth</tabstop>
+ <tabstop>cbWrapping</tabstop>
+ <tabstop>sbLineLength</tabstop>
+ <tabstop>cbAdvWrapping</tabstop>
+ <tabstop>comboFontName</tabstop>
+ <tabstop>leFontSize</tabstop>
+ <tabstop>browserPreview</tabstop>
+ <tabstop>pbStartConversion</tabstop>
+ <tabstop>pbCopyFile2CP</tabstop>
+ </tabstops>
+ <resources>
+ <include location="highlight-gui.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>pbClearAll</sender>
+ <signal>clicked()</signal>
+ <receiver>lvInputFiles</receiver>
+ <slot>clear()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>285</x>
+ <y>420</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>218</x>
+ <y>228</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/support/highlight/src/gui-qt/moc_io_report.cpp b/support/highlight/src/gui-qt/moc_io_report.cpp
new file mode 100644
index 0000000000..1b6ef11f60
--- /dev/null
+++ b/support/highlight/src/gui-qt/moc_io_report.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'io_report.h'
+**
+** Created: Wed Mar 31 16:43:41 2010
+** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "io_report.h"
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'io_report.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 62
+#error "This file was generated using the moc from 4.6.2. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+static const uint qt_meta_data_io_report[] = {
+
+ // content:
+ 4, // revision
+ 0, // classname
+ 0, 0, // classinfo
+ 0, 0, // methods
+ 0, 0, // properties
+ 0, 0, // enums/sets
+ 0, 0, // constructors
+ 0, // flags
+ 0, // signalCount
+
+ 0 // eod
+};
+
+static const char qt_meta_stringdata_io_report[] = {
+ "io_report\0"
+};
+
+const QMetaObject io_report::staticMetaObject = {
+ { &QDialog::staticMetaObject, qt_meta_stringdata_io_report,
+ qt_meta_data_io_report, 0 }
+};
+
+#ifdef Q_NO_DATA_RELOCATION
+const QMetaObject &io_report::getStaticMetaObject() { return staticMetaObject; }
+#endif //Q_NO_DATA_RELOCATION
+
+const QMetaObject *io_report::metaObject() const
+{
+ return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
+}
+
+void *io_report::qt_metacast(const char *_clname)
+{
+ if (!_clname) return 0;
+ if (!strcmp(_clname, qt_meta_stringdata_io_report))
+ return static_cast<void*>(const_cast< io_report*>(this));
+ return QDialog::qt_metacast(_clname);
+}
+
+int io_report::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+ _id = QDialog::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+ return _id;
+}
+QT_END_MOC_NAMESPACE
diff --git a/support/highlight/src/gui-qt/moc_mainwindow.cpp b/support/highlight/src/gui-qt/moc_mainwindow.cpp
new file mode 100644
index 0000000000..2182a76b07
--- /dev/null
+++ b/support/highlight/src/gui-qt/moc_mainwindow.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'mainwindow.h'
+**
+** Created: Wed Mar 31 16:43:41 2010
+** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "mainwindow.h"
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'mainwindow.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 62
+#error "This file was generated using the moc from 4.6.2. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+static const uint qt_meta_data_MainWindow[] = {
+
+ // content:
+ 4, // revision
+ 0, // classname
+ 0, 0, // classinfo
+ 20, 14, // methods
+ 0, 0, // properties
+ 0, 0, // enums/sets
+ 0, 0, // constructors
+ 0, // flags
+ 0, // signalCount
+
+ // slots: signature, parameters, type, tag, flags
+ 12, 11, 11, 11, 0x0a,
+ 42, 11, 11, 11, 0x0a,
+ 68, 11, 11, 11, 0x0a,
+ 99, 11, 11, 11, 0x0a,
+ 126, 11, 11, 11, 0x08,
+ 150, 11, 11, 11, 0x08,
+ 177, 11, 11, 11, 0x08,
+ 217, 11, 11, 11, 0x08,
+ 254, 11, 11, 11, 0x08,
+ 293, 11, 11, 11, 0x08,
+ 331, 11, 11, 11, 0x08,
+ 368, 11, 11, 11, 0x08,
+ 398, 11, 11, 11, 0x08,
+ 430, 11, 11, 11, 0x08,
+ 459, 11, 11, 11, 0x08,
+ 493, 11, 11, 11, 0x08,
+ 531, 11, 11, 11, 0x08,
+ 558, 11, 11, 11, 0x08,
+ 573, 11, 11, 11, 0x08,
+ 589, 11, 11, 11, 0x08,
+
+ 0 // eod
+};
+
+static const char qt_meta_stringdata_MainWindow[] = {
+ "MainWindow\0\0on_pbClearSelection_clicked()\0"
+ "on_pbOutputDest_clicked()\0"
+ "on_pbStartConversion_clicked()\0"
+ "on_pbCopyFile2CP_clicked()\0"
+ "on_pbCopyToCP_clicked()\0"
+ "on_pbPasteFromCB_clicked()\0"
+ "on_actionAbout_translations_triggered()\0"
+ "on_pbTEXChooseStyleIncFile_clicked()\0"
+ "on_pbLATEXChooseStyleIncFile_clicked()\0"
+ "on_pbHTMLChooseStyleIncFile_clicked()\0"
+ "on_pbSVGChooseStyleIncFile_clicked()\0"
+ "on_action_License_triggered()\0"
+ "on_action_Changelog_triggered()\0"
+ "on_action_Manual_triggered()\0"
+ "on_pbHTMLChooseTagsFile_clicked()\0"
+ "on_action_About_Highlight_triggered()\0"
+ "on_action_Exit_triggered()\0plausibility()\0"
+ "updatePreview()\0openFiles()\0"
+};
+
+const QMetaObject MainWindow::staticMetaObject = {
+ { &QMainWindow::staticMetaObject, qt_meta_stringdata_MainWindow,
+ qt_meta_data_MainWindow, 0 }
+};
+
+#ifdef Q_NO_DATA_RELOCATION
+const QMetaObject &MainWindow::getStaticMetaObject() { return staticMetaObject; }
+#endif //Q_NO_DATA_RELOCATION
+
+const QMetaObject *MainWindow::metaObject() const
+{
+ return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
+}
+
+void *MainWindow::qt_metacast(const char *_clname)
+{
+ if (!_clname) return 0;
+ if (!strcmp(_clname, qt_meta_stringdata_MainWindow))
+ return static_cast<void*>(const_cast< MainWindow*>(this));
+ return QMainWindow::qt_metacast(_clname);
+}
+
+int MainWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+ _id = QMainWindow::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+ if (_c == QMetaObject::InvokeMetaMethod) {
+ switch (_id) {
+ case 0: on_pbClearSelection_clicked(); break;
+ case 1: on_pbOutputDest_clicked(); break;
+ case 2: on_pbStartConversion_clicked(); break;
+ case 3: on_pbCopyFile2CP_clicked(); break;
+ case 4: on_pbCopyToCP_clicked(); break;
+ case 5: on_pbPasteFromCB_clicked(); break;
+ case 6: on_actionAbout_translations_triggered(); break;
+ case 7: on_pbTEXChooseStyleIncFile_clicked(); break;
+ case 8: on_pbLATEXChooseStyleIncFile_clicked(); break;
+ case 9: on_pbHTMLChooseStyleIncFile_clicked(); break;
+ case 10: on_pbSVGChooseStyleIncFile_clicked(); break;
+ case 11: on_action_License_triggered(); break;
+ case 12: on_action_Changelog_triggered(); break;
+ case 13: on_action_Manual_triggered(); break;
+ case 14: on_pbHTMLChooseTagsFile_clicked(); break;
+ case 15: on_action_About_Highlight_triggered(); break;
+ case 16: on_action_Exit_triggered(); break;
+ case 17: plausibility(); break;
+ case 18: updatePreview(); break;
+ case 19: openFiles(); break;
+ default: ;
+ }
+ _id -= 20;
+ }
+ return _id;
+}
+QT_END_MOC_NAMESPACE
diff --git a/support/highlight/src/gui-qt/moc_showtextfile.cpp b/support/highlight/src/gui-qt/moc_showtextfile.cpp
new file mode 100644
index 0000000000..dfd8aa34f6
--- /dev/null
+++ b/support/highlight/src/gui-qt/moc_showtextfile.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'showtextfile.h'
+**
+** Created: Wed Mar 31 16:43:42 2010
+** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "showtextfile.h"
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'showtextfile.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 62
+#error "This file was generated using the moc from 4.6.2. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+static const uint qt_meta_data_ShowTextFile[] = {
+
+ // content:
+ 4, // revision
+ 0, // classname
+ 0, 0, // classinfo
+ 1, 14, // methods
+ 0, 0, // properties
+ 0, 0, // enums/sets
+ 0, 0, // constructors
+ 0, // flags
+ 0, // signalCount
+
+ // slots: signature, parameters, type, tag, flags
+ 14, 13, 13, 13, 0x08,
+
+ 0 // eod
+};
+
+static const char qt_meta_stringdata_ShowTextFile[] = {
+ "ShowTextFile\0\0on_pushButton_clicked()\0"
+};
+
+const QMetaObject ShowTextFile::staticMetaObject = {
+ { &QDialog::staticMetaObject, qt_meta_stringdata_ShowTextFile,
+ qt_meta_data_ShowTextFile, 0 }
+};
+
+#ifdef Q_NO_DATA_RELOCATION
+const QMetaObject &ShowTextFile::getStaticMetaObject() { return staticMetaObject; }
+#endif //Q_NO_DATA_RELOCATION
+
+const QMetaObject *ShowTextFile::metaObject() const
+{
+ return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
+}
+
+void *ShowTextFile::qt_metacast(const char *_clname)
+{
+ if (!_clname) return 0;
+ if (!strcmp(_clname, qt_meta_stringdata_ShowTextFile))
+ return static_cast<void*>(const_cast< ShowTextFile*>(this));
+ return QDialog::qt_metacast(_clname);
+}
+
+int ShowTextFile::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+ _id = QDialog::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+ if (_c == QMetaObject::InvokeMetaMethod) {
+ switch (_id) {
+ case 0: on_pushButton_clicked(); break;
+ default: ;
+ }
+ _id -= 1;
+ }
+ return _id;
+}
+QT_END_MOC_NAMESPACE
diff --git a/support/highlight/src/gui-qt/precomp.h b/support/highlight/src/gui-qt/precomp.h
new file mode 100644
index 0000000000..28d089ae02
--- /dev/null
+++ b/support/highlight/src/gui-qt/precomp.h
@@ -0,0 +1,26 @@
+#ifndef PRECOMP_H
+#define PRECOMP_H
+
+#if defined __cplusplus
+#include <QtGui/QMainWindow>
+#include <QtGui/QMessageBox>
+#include <QtGui/QFileDialog>
+#include <QSettings>
+#include <QDir>
+#include <QClipboard>
+#include <QMimeData>
+#include <QTime>
+#include <QLineEdit>
+#include <QString>
+#include <QTextStream>
+#include <QDropEvent>
+
+#include "version.h"
+#include "codegenerator.h"
+#include "htmlgenerator.h"
+#include "configurationreader.h"
+
+#include "enums.h"
+#endif
+
+#endif // PRECOMP_H
diff --git a/support/highlight/src/gui-qt/showtextfile.cpp b/support/highlight/src/gui-qt/showtextfile.cpp
new file mode 100644
index 0000000000..dffdd131e8
--- /dev/null
+++ b/support/highlight/src/gui-qt/showtextfile.cpp
@@ -0,0 +1,72 @@
+
+/***************************************************************************
+ showtestfile.cpp
+ -------------------
+ begin : Mo 16.03.2009
+ copyright : (C) 2009 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "showtextfile.h"
+#include "ui_showtextfile.h"
+#include <QTextStream>
+
+ShowTextFile::ShowTextFile(QWidget *parent) :
+ QDialog(parent),
+ m_ui(new Ui::ShowTextFile)
+{
+ m_ui->setupUi(this);
+}
+
+ShowTextFile::~ShowTextFile()
+{
+ delete m_ui;
+}
+
+void ShowTextFile::changeEvent(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ m_ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+
+bool ShowTextFile::setFileName(const QString& fileName){
+#ifndef HL_DOC_DIR
+ QFile file( QString("%1/%2").arg(QDir::currentPath()).arg( fileName ));
+#else
+ QFile file( QString("%1/%2").arg(HL_DOC_DIR).arg(fileName ));
+#endif
+ if ( file.open( QIODevice::ReadOnly) ) {
+ QTextStream stream( &file );
+ m_ui->textEdit->setText( stream.readAll() );
+ m_ui->lbTitle->setText(fileName);
+ }
+ return file.exists();
+}
+
+void ShowTextFile::on_pushButton_clicked()
+{
+ this->close();
+}
diff --git a/support/highlight/src/gui-qt/showtextfile.h b/support/highlight/src/gui-qt/showtextfile.h
new file mode 100644
index 0000000000..8840633ec6
--- /dev/null
+++ b/support/highlight/src/gui-qt/showtextfile.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ showtextfile.h
+ -------------------
+ begin : Mo 16.03.2009
+ copyright : (C) 2009 by Andre Simon
+ email : andre.simon1@gmx.de
+ ***************************************************************************/
+
+/*
+This file is part of Highlight.
+
+Highlight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Highlight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Highlight. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SHOWTEXTFILE_H
+#define SHOWTEXTFILE_H
+
+#include <QtGui/QDialog>
+
+
+namespace Ui {
+ class ShowTextFile;
+}
+
+class ShowTextFile : public QDialog {
+ Q_OBJECT
+ Q_DISABLE_COPY(ShowTextFile)
+public:
+ explicit ShowTextFile(QWidget *parent = 0);
+ virtual ~ShowTextFile();
+ bool setFileName(const QString& fileName);
+
+protected:
+ virtual void changeEvent(QEvent *e);
+
+private:
+ Ui::ShowTextFile *m_ui;
+
+private slots:
+ void on_pushButton_clicked();
+};
+
+#endif // SHOWTEXTFILE_H
diff --git a/support/highlight/src/gui-qt/showtextfile.ui b/support/highlight/src/gui-qt/showtextfile.ui
new file mode 100644
index 0000000000..095ff23729
--- /dev/null
+++ b/support/highlight/src/gui-qt/showtextfile.ui
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ShowTextFile</class>
+ <widget class="QDialog" name="ShowTextFile">
+ <property name="windowModality">
+ <enum>Qt::WindowModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>711</width>
+ <height>442</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Show text</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="highlight-gui.qrc">
+ <normaloff>:/hl_icon2.png</normaloff>:/hl_icon2.png</iconset>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="lbTitle">
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="textEdit">
+ <property name="font">
+ <font>
+ <family>Courier New</family>
+ <pointsize>8</pointsize>
+ </font>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButton">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="highlight-gui.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/support/highlight/src/gui-qt/ui_io_report.h b/support/highlight/src/gui-qt/ui_io_report.h
new file mode 100644
index 0000000000..e9eaad349e
--- /dev/null
+++ b/support/highlight/src/gui-qt/ui_io_report.h
@@ -0,0 +1,134 @@
+/********************************************************************************
+** Form generated from reading UI file 'io_report.ui'
+**
+** Created: Wed Mar 31 16:43:25 2010
+** by: Qt User Interface Compiler version 4.6.2
+**
+** WARNING! All changes made in this file will be lost when recompiling UI file!
+********************************************************************************/
+
+#ifndef UI_IO_REPORT_H
+#define UI_IO_REPORT_H
+
+#include <QtCore/QVariant>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QCheckBox>
+#include <QtGui/QDialog>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QFrame>
+#include <QtGui/QHeaderView>
+#include <QtGui/QLabel>
+#include <QtGui/QListWidget>
+#include <QtGui/QVBoxLayout>
+
+QT_BEGIN_NAMESPACE
+
+class Ui_io_report
+{
+public:
+ QVBoxLayout *verticalLayout;
+ QLabel *label_2;
+ QListWidget *listInputErrors;
+ QCheckBox *cbRemoveFiles;
+ QFrame *line;
+ QLabel *label;
+ QListWidget *listOutputErrors;
+ QFrame *line_2;
+ QLabel *label_3;
+ QListWidget *listReformatErrors;
+ QDialogButtonBox *buttonBox;
+
+ void setupUi(QDialog *io_report)
+ {
+ if (io_report->objectName().isEmpty())
+ io_report->setObjectName(QString::fromUtf8("io_report"));
+ io_report->resize(436, 372);
+ QIcon icon;
+ icon.addFile(QString::fromUtf8(":/hl_icon2.png"), QSize(), QIcon::Normal, QIcon::Off);
+ io_report->setWindowIcon(icon);
+ verticalLayout = new QVBoxLayout(io_report);
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
+ label_2 = new QLabel(io_report);
+ label_2->setObjectName(QString::fromUtf8("label_2"));
+
+ verticalLayout->addWidget(label_2);
+
+ listInputErrors = new QListWidget(io_report);
+ listInputErrors->setObjectName(QString::fromUtf8("listInputErrors"));
+
+ verticalLayout->addWidget(listInputErrors);
+
+ cbRemoveFiles = new QCheckBox(io_report);
+ cbRemoveFiles->setObjectName(QString::fromUtf8("cbRemoveFiles"));
+
+ verticalLayout->addWidget(cbRemoveFiles);
+
+ line = new QFrame(io_report);
+ line->setObjectName(QString::fromUtf8("line"));
+ line->setFrameShape(QFrame::HLine);
+ line->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout->addWidget(line);
+
+ label = new QLabel(io_report);
+ label->setObjectName(QString::fromUtf8("label"));
+
+ verticalLayout->addWidget(label);
+
+ listOutputErrors = new QListWidget(io_report);
+ listOutputErrors->setObjectName(QString::fromUtf8("listOutputErrors"));
+
+ verticalLayout->addWidget(listOutputErrors);
+
+ line_2 = new QFrame(io_report);
+ line_2->setObjectName(QString::fromUtf8("line_2"));
+ line_2->setFrameShape(QFrame::HLine);
+ line_2->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout->addWidget(line_2);
+
+ label_3 = new QLabel(io_report);
+ label_3->setObjectName(QString::fromUtf8("label_3"));
+
+ verticalLayout->addWidget(label_3);
+
+ listReformatErrors = new QListWidget(io_report);
+ listReformatErrors->setObjectName(QString::fromUtf8("listReformatErrors"));
+
+ verticalLayout->addWidget(listReformatErrors);
+
+ buttonBox = new QDialogButtonBox(io_report);
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
+ buttonBox->setOrientation(Qt::Horizontal);
+ buttonBox->setStandardButtons(QDialogButtonBox::Ok);
+
+ verticalLayout->addWidget(buttonBox);
+
+
+ retranslateUi(io_report);
+ QObject::connect(buttonBox, SIGNAL(accepted()), io_report, SLOT(accept()));
+ QObject::connect(buttonBox, SIGNAL(rejected()), io_report, SLOT(reject()));
+
+ QMetaObject::connectSlotsByName(io_report);
+ } // setupUi
+
+ void retranslateUi(QDialog *io_report)
+ {
+ io_report->setWindowTitle(QApplication::translate("io_report", "Error summary", 0, QApplication::UnicodeUTF8));
+ label_2->setText(QApplication::translate("io_report", "Input errors:", 0, QApplication::UnicodeUTF8));
+ cbRemoveFiles->setText(QApplication::translate("io_report", "Remove files above from input file list", 0, QApplication::UnicodeUTF8));
+ label->setText(QApplication::translate("io_report", "Output errors:", 0, QApplication::UnicodeUTF8));
+ label_3->setText(QApplication::translate("io_report", "Reformatting not possible:", 0, QApplication::UnicodeUTF8));
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class io_report: public Ui_io_report {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // UI_IO_REPORT_H
diff --git a/support/highlight/src/gui-qt/ui_mainwindow.h b/support/highlight/src/gui-qt/ui_mainwindow.h
new file mode 100644
index 0000000000..ca73d3b551
--- /dev/null
+++ b/support/highlight/src/gui-qt/ui_mainwindow.h
@@ -0,0 +1,1860 @@
+/********************************************************************************
+** Form generated from reading UI file 'mainwindow.ui'
+**
+** Created: Wed Mar 31 16:43:25 2010
+** by: Qt User Interface Compiler version 4.6.2
+**
+** WARNING! All changes made in this file will be lost when recompiling UI file!
+********************************************************************************/
+
+#ifndef UI_MAINWINDOW_H
+#define UI_MAINWINDOW_H
+
+#include <QtCore/QVariant>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QCheckBox>
+#include <QtGui/QComboBox>
+#include <QtGui/QFontComboBox>
+#include <QtGui/QFrame>
+#include <QtGui/QGridLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QHeaderView>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QListWidget>
+#include <QtGui/QMainWindow>
+#include <QtGui/QMenu>
+#include <QtGui/QMenuBar>
+#include <QtGui/QProgressBar>
+#include <QtGui/QPushButton>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QSpinBox>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QStatusBar>
+#include <QtGui/QTabWidget>
+#include <QtGui/QTextBrowser>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class Ui_MainWindowClass
+{
+public:
+ QAction *action_Open_files;
+ QAction *action_Exit;
+ QAction *action_Load;
+ QAction *action_Save;
+ QAction *actionLoad_default_project;
+ QAction *action_Manual;
+ QAction *action_Tips;
+ QAction *action_Changelog;
+ QAction *action_License;
+ QAction *action_About_Highlight;
+ QAction *actionAbout_translations;
+ QWidget *centralWidget;
+ QHBoxLayout *horizontalLayout_24;
+ QVBoxLayout *verticalLayout_7;
+ QTabWidget *tabIOSelection;
+ QWidget *tab_file_io;
+ QVBoxLayout *verticalLayout_3;
+ QPushButton *pbOpenFiles;
+ QListWidget *lvInputFiles;
+ QHBoxLayout *horizontalLayout;
+ QPushButton *pbClearSelection;
+ QPushButton *pbClearAll;
+ QFrame *line_11;
+ QVBoxLayout *verticalLayout;
+ QLabel *label_11;
+ QHBoxLayout *horizontalLayout_22;
+ QLineEdit *leOutputDest;
+ QPushButton *pbOutputDest;
+ QCheckBox *cbWrite2Src;
+ QFrame *line_2;
+ QPushButton *pbStartConversion;
+ QPushButton *pbCopyFile2CP;
+ QWidget *tab_clipboard;
+ QVBoxLayout *verticalLayout_15;
+ QPushButton *pbPasteFromCB;
+ QHBoxLayout *horizontalLayout_23;
+ QLabel *label_13;
+ QComboBox *comboSelectSyntax;
+ QFrame *line_14;
+ QPushButton *pbCopyToCP;
+ QSpacerItem *verticalSpacer_12;
+ QFrame *line_7;
+ QTabWidget *tabWidget;
+ QWidget *page_general;
+ QVBoxLayout *verticalLayout_2;
+ QHBoxLayout *horizontalLayout_8;
+ QLabel *label_2;
+ QComboBox *comboFormat;
+ QFrame *line_9;
+ QHBoxLayout *horizontalLayout_21;
+ QCheckBox *cbIncLineNo;
+ QSpacerItem *horizontalSpacer_4;
+ QSpinBox *sbLineNoWidth;
+ QCheckBox *cbPadZeroes;
+ QCheckBox *cbFragment;
+ QCheckBox *cbValidateInput;
+ QHBoxLayout *horizontalLayout_2;
+ QCheckBox *cbEncoding;
+ QComboBox *comboEncoding;
+ QSpacerItem *verticalSpacer_2;
+ QWidget *page_output_spec;
+ QGridLayout *gridLayout;
+ QStackedWidget *stackedSpecificOptions;
+ QWidget *HTMLOptions;
+ QVBoxLayout *verticalLayout_5;
+ QLabel *label_17;
+ QFrame *line_12;
+ QTabWidget *tabWidget1;
+ QWidget *tabWidgetPage1;
+ QGridLayout *gridLayout_4;
+ QHBoxLayout *horizontalLayout_10;
+ QCheckBox *cbHTMLEmbedStyle;
+ QCheckBox *cbHTMLInlineCSS;
+ QHBoxLayout *horizontalLayout_14;
+ QLabel *label_19;
+ QLineEdit *leHTMLStyleFile;
+ QHBoxLayout *horizontalLayout_9;
+ QLabel *label_20;
+ QLineEdit *leHTMLStyleIncFile;
+ QPushButton *pbHTMLChooseStyleIncFile;
+ QHBoxLayout *horizontalLayout_7;
+ QLabel *label;
+ QLineEdit *leHTMLCssPrefix;
+ QSpacerItem *verticalSpacer_9;
+ QWidget *tabWidgetPage2;
+ QVBoxLayout *verticalLayout_6;
+ QCheckBox *cbHTMLIndex;
+ QFrame *line_13;
+ QCheckBox *cbHTMLCtags;
+ QHBoxLayout *horizontalLayout_12;
+ QLineEdit *leHTMLCtagsFile;
+ QPushButton *pbHTMLChooseTagsFile;
+ QSpacerItem *verticalSpacer_8;
+ QWidget *tabWidgetPage3;
+ QVBoxLayout *verticalLayout_4;
+ QLabel *label_8;
+ QCheckBox *cbHTMLAnchors;
+ QCheckBox *cbHTMLFileNameAnchor;
+ QCheckBox *cbHTMLOrderedList;
+ QFrame *line_4;
+ QCheckBox *cbHTMLEnclosePreTags;
+ QSpacerItem *verticalSpacer;
+ QWidget *LATEXOptions;
+ QVBoxLayout *verticalLayout_12;
+ QLabel *label_18;
+ QFrame *line_8;
+ QCheckBox *cbLATEXEscQuotes;
+ QCheckBox *cbLATEXBabel;
+ QCheckBox *cbLATEXPrettySymbols;
+ QCheckBox *cbLATEXEmbedStyle;
+ QHBoxLayout *horizontalLayout_17;
+ QLabel *label_21;
+ QLineEdit *leLATEXStyleFile;
+ QHBoxLayout *horizontalLayout_15;
+ QLabel *label_22;
+ QSpacerItem *horizontalSpacer_2;
+ QHBoxLayout *horizontalLayout_16;
+ QLineEdit *leLATEXStyleIncFile;
+ QPushButton *pbLATEXChooseStyleIncFile;
+ QSpacerItem *verticalSpacer_4;
+ QWidget *TEXOptions;
+ QVBoxLayout *verticalLayout_14;
+ QLabel *label_26;
+ QFrame *line_10;
+ QCheckBox *cbTEXEmbedStyle;
+ QHBoxLayout *horizontalLayout_18;
+ QLabel *label_24;
+ QLineEdit *leTEXStyleFile;
+ QHBoxLayout *horizontalLayout_19;
+ QLabel *label_25;
+ QSpacerItem *horizontalSpacer_3;
+ QHBoxLayout *horizontalLayout_20;
+ QLineEdit *leTEXStyleIncFile;
+ QPushButton *pbTEXChooseStyleIncFile;
+ QSpacerItem *verticalSpacer_5;
+ QWidget *RTFOptions;
+ QVBoxLayout *verticalLayout_9;
+ QLabel *label_15;
+ QFrame *line_5;
+ QCheckBox *cbRTFCharStyles;
+ QHBoxLayout *horizontalLayout_11;
+ QLabel *label_9;
+ QComboBox *comboRTFPageSize;
+ QSpacerItem *verticalSpacer_6;
+ QWidget *SVGOptions;
+ QVBoxLayout *verticalLayout_10;
+ QLabel *label_16;
+ QFrame *line_6;
+ QLabel *label_10;
+ QGridLayout *gridLayout_8;
+ QLabel *label_3;
+ QLineEdit *leSVGWidth;
+ QLabel *label_12;
+ QLineEdit *leSVGHeight;
+ QCheckBox *cbSVGEmbedStyle;
+ QHBoxLayout *horizontalLayout_26;
+ QLabel *label_29;
+ QLineEdit *leSVGStyleFile;
+ QHBoxLayout *horizontalLayout_27;
+ QLabel *label_30;
+ QSpacerItem *horizontalSpacer_6;
+ QHBoxLayout *horizontalLayout_28;
+ QLineEdit *leSVGStyleIncFile;
+ QPushButton *pbSVGChooseStyleIncFile;
+ QSpacerItem *verticalSpacer_10;
+ QWidget *EmptyPage;
+ QVBoxLayout *verticalLayout_11;
+ QLabel *label_7;
+ QSpacerItem *verticalSpacer_3;
+ QWidget *page_formatting;
+ QVBoxLayout *verticalLayout_8;
+ QHBoxLayout *horizontalLayout_3;
+ QLabel *label_5;
+ QComboBox *comboTheme;
+ QHBoxLayout *horizontalLayout_4;
+ QCheckBox *cbReformat;
+ QComboBox *comboReformat;
+ QHBoxLayout *horizontalLayout_5;
+ QCheckBox *cbKwCase;
+ QComboBox *comboKwCase;
+ QHBoxLayout *horizontalLayout_6;
+ QLabel *label_6;
+ QSpinBox *sbTabWidth;
+ QGridLayout *gridLayout_2;
+ QCheckBox *cbWrapping;
+ QSpinBox *sbLineLength;
+ QCheckBox *cbAdvWrapping;
+ QSpacerItem *verticalSpacer_11;
+ QFrame *line_3;
+ QGridLayout *gridLayout_9;
+ QLabel *label_23;
+ QFontComboBox *comboFontName;
+ QLabel *label_4;
+ QLineEdit *leFontSize;
+ QFrame *line;
+ QVBoxLayout *verticalLayout_13;
+ QLabel *lbPreview;
+ QTextBrowser *browserPreview;
+ QHBoxLayout *horizontalLayout_13;
+ QLabel *label_14;
+ QProgressBar *progressBar;
+ QMenuBar *menuBar;
+ QMenu *menu_File;
+ QMenu *menu_Help;
+ QStatusBar *statusBar;
+
+ void setupUi(QMainWindow *MainWindowClass)
+ {
+ if (MainWindowClass->objectName().isEmpty())
+ MainWindowClass->setObjectName(QString::fromUtf8("MainWindowClass"));
+ MainWindowClass->setWindowModality(Qt::ApplicationModal);
+ MainWindowClass->resize(600, 645);
+ MainWindowClass->setAcceptDrops(false);
+ QIcon icon;
+ icon.addFile(QString::fromUtf8(":/hl_icon2.png"), QSize(), QIcon::Normal, QIcon::Off);
+ MainWindowClass->setWindowIcon(icon);
+ action_Open_files = new QAction(MainWindowClass);
+ action_Open_files->setObjectName(QString::fromUtf8("action_Open_files"));
+ action_Exit = new QAction(MainWindowClass);
+ action_Exit->setObjectName(QString::fromUtf8("action_Exit"));
+ action_Load = new QAction(MainWindowClass);
+ action_Load->setObjectName(QString::fromUtf8("action_Load"));
+ action_Save = new QAction(MainWindowClass);
+ action_Save->setObjectName(QString::fromUtf8("action_Save"));
+ actionLoad_default_project = new QAction(MainWindowClass);
+ actionLoad_default_project->setObjectName(QString::fromUtf8("actionLoad_default_project"));
+ action_Manual = new QAction(MainWindowClass);
+ action_Manual->setObjectName(QString::fromUtf8("action_Manual"));
+ action_Tips = new QAction(MainWindowClass);
+ action_Tips->setObjectName(QString::fromUtf8("action_Tips"));
+ action_Tips->setVisible(false);
+ action_Changelog = new QAction(MainWindowClass);
+ action_Changelog->setObjectName(QString::fromUtf8("action_Changelog"));
+ action_License = new QAction(MainWindowClass);
+ action_License->setObjectName(QString::fromUtf8("action_License"));
+ action_About_Highlight = new QAction(MainWindowClass);
+ action_About_Highlight->setObjectName(QString::fromUtf8("action_About_Highlight"));
+ actionAbout_translations = new QAction(MainWindowClass);
+ actionAbout_translations->setObjectName(QString::fromUtf8("actionAbout_translations"));
+ centralWidget = new QWidget(MainWindowClass);
+ centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
+ horizontalLayout_24 = new QHBoxLayout(centralWidget);
+ horizontalLayout_24->setSpacing(6);
+ horizontalLayout_24->setContentsMargins(11, 11, 11, 11);
+ horizontalLayout_24->setObjectName(QString::fromUtf8("horizontalLayout_24"));
+ verticalLayout_7 = new QVBoxLayout();
+ verticalLayout_7->setSpacing(6);
+ verticalLayout_7->setObjectName(QString::fromUtf8("verticalLayout_7"));
+ tabIOSelection = new QTabWidget(centralWidget);
+ tabIOSelection->setObjectName(QString::fromUtf8("tabIOSelection"));
+ QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ sizePolicy.setHeightForWidth(tabIOSelection->sizePolicy().hasHeightForWidth());
+ tabIOSelection->setSizePolicy(sizePolicy);
+ tabIOSelection->setMinimumSize(QSize(0, 0));
+ tab_file_io = new QWidget();
+ tab_file_io->setObjectName(QString::fromUtf8("tab_file_io"));
+ verticalLayout_3 = new QVBoxLayout(tab_file_io);
+ verticalLayout_3->setSpacing(6);
+ verticalLayout_3->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3"));
+ pbOpenFiles = new QPushButton(tab_file_io);
+ pbOpenFiles->setObjectName(QString::fromUtf8("pbOpenFiles"));
+
+ verticalLayout_3->addWidget(pbOpenFiles);
+
+ lvInputFiles = new QListWidget(tab_file_io);
+ lvInputFiles->setObjectName(QString::fromUtf8("lvInputFiles"));
+ QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
+ sizePolicy1.setHorizontalStretch(0);
+ sizePolicy1.setVerticalStretch(0);
+ sizePolicy1.setHeightForWidth(lvInputFiles->sizePolicy().hasHeightForWidth());
+ lvInputFiles->setSizePolicy(sizePolicy1);
+ lvInputFiles->setMinimumSize(QSize(0, 50));
+ lvInputFiles->setAcceptDrops(false);
+ lvInputFiles->setDragDropMode(QAbstractItemView::DropOnly);
+ lvInputFiles->setAlternatingRowColors(true);
+ lvInputFiles->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ lvInputFiles->setSelectionBehavior(QAbstractItemView::SelectRows);
+
+ verticalLayout_3->addWidget(lvInputFiles);
+
+ horizontalLayout = new QHBoxLayout();
+ horizontalLayout->setSpacing(6);
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
+ pbClearSelection = new QPushButton(tab_file_io);
+ pbClearSelection->setObjectName(QString::fromUtf8("pbClearSelection"));
+
+ horizontalLayout->addWidget(pbClearSelection);
+
+ pbClearAll = new QPushButton(tab_file_io);
+ pbClearAll->setObjectName(QString::fromUtf8("pbClearAll"));
+
+ horizontalLayout->addWidget(pbClearAll);
+
+
+ verticalLayout_3->addLayout(horizontalLayout);
+
+ line_11 = new QFrame(tab_file_io);
+ line_11->setObjectName(QString::fromUtf8("line_11"));
+ line_11->setFrameShape(QFrame::HLine);
+ line_11->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_3->addWidget(line_11);
+
+ verticalLayout = new QVBoxLayout();
+ verticalLayout->setSpacing(6);
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
+ label_11 = new QLabel(tab_file_io);
+ label_11->setObjectName(QString::fromUtf8("label_11"));
+ QFont font;
+ font.setBold(true);
+ font.setWeight(75);
+ label_11->setFont(font);
+
+ verticalLayout->addWidget(label_11);
+
+ horizontalLayout_22 = new QHBoxLayout();
+ horizontalLayout_22->setSpacing(6);
+ horizontalLayout_22->setObjectName(QString::fromUtf8("horizontalLayout_22"));
+ leOutputDest = new QLineEdit(tab_file_io);
+ leOutputDest->setObjectName(QString::fromUtf8("leOutputDest"));
+ QSizePolicy sizePolicy2(QSizePolicy::Minimum, QSizePolicy::Preferred);
+ sizePolicy2.setHorizontalStretch(0);
+ sizePolicy2.setVerticalStretch(0);
+ sizePolicy2.setHeightForWidth(leOutputDest->sizePolicy().hasHeightForWidth());
+ leOutputDest->setSizePolicy(sizePolicy2);
+
+ horizontalLayout_22->addWidget(leOutputDest);
+
+ pbOutputDest = new QPushButton(tab_file_io);
+ pbOutputDest->setObjectName(QString::fromUtf8("pbOutputDest"));
+ QSizePolicy sizePolicy3(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ sizePolicy3.setHorizontalStretch(0);
+ sizePolicy3.setVerticalStretch(0);
+ sizePolicy3.setHeightForWidth(pbOutputDest->sizePolicy().hasHeightForWidth());
+ pbOutputDest->setSizePolicy(sizePolicy3);
+ pbOutputDest->setMinimumSize(QSize(20, 0));
+
+ horizontalLayout_22->addWidget(pbOutputDest);
+
+
+ verticalLayout->addLayout(horizontalLayout_22);
+
+ cbWrite2Src = new QCheckBox(tab_file_io);
+ cbWrite2Src->setObjectName(QString::fromUtf8("cbWrite2Src"));
+
+ verticalLayout->addWidget(cbWrite2Src);
+
+
+ verticalLayout_3->addLayout(verticalLayout);
+
+ line_2 = new QFrame(tab_file_io);
+ line_2->setObjectName(QString::fromUtf8("line_2"));
+ line_2->setFrameShape(QFrame::HLine);
+ line_2->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_3->addWidget(line_2);
+
+ pbStartConversion = new QPushButton(tab_file_io);
+ pbStartConversion->setObjectName(QString::fromUtf8("pbStartConversion"));
+ QSizePolicy sizePolicy4(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ sizePolicy4.setHorizontalStretch(0);
+ sizePolicy4.setVerticalStretch(0);
+ sizePolicy4.setHeightForWidth(pbStartConversion->sizePolicy().hasHeightForWidth());
+ pbStartConversion->setSizePolicy(sizePolicy4);
+ pbStartConversion->setMinimumSize(QSize(120, 0));
+ QFont font1;
+ font1.setFamily(QString::fromUtf8("MS Shell Dlg 2"));
+ font1.setPointSize(10);
+ font1.setBold(true);
+ font1.setWeight(75);
+ pbStartConversion->setFont(font1);
+ pbStartConversion->setDefault(true);
+
+ verticalLayout_3->addWidget(pbStartConversion);
+
+ pbCopyFile2CP = new QPushButton(tab_file_io);
+ pbCopyFile2CP->setObjectName(QString::fromUtf8("pbCopyFile2CP"));
+
+ verticalLayout_3->addWidget(pbCopyFile2CP);
+
+ tabIOSelection->addTab(tab_file_io, QString());
+ tab_clipboard = new QWidget();
+ tab_clipboard->setObjectName(QString::fromUtf8("tab_clipboard"));
+ verticalLayout_15 = new QVBoxLayout(tab_clipboard);
+ verticalLayout_15->setSpacing(6);
+ verticalLayout_15->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_15->setObjectName(QString::fromUtf8("verticalLayout_15"));
+ pbPasteFromCB = new QPushButton(tab_clipboard);
+ pbPasteFromCB->setObjectName(QString::fromUtf8("pbPasteFromCB"));
+
+ verticalLayout_15->addWidget(pbPasteFromCB);
+
+ horizontalLayout_23 = new QHBoxLayout();
+ horizontalLayout_23->setSpacing(6);
+ horizontalLayout_23->setObjectName(QString::fromUtf8("horizontalLayout_23"));
+ label_13 = new QLabel(tab_clipboard);
+ label_13->setObjectName(QString::fromUtf8("label_13"));
+
+ horizontalLayout_23->addWidget(label_13);
+
+ comboSelectSyntax = new QComboBox(tab_clipboard);
+ comboSelectSyntax->setObjectName(QString::fromUtf8("comboSelectSyntax"));
+
+ horizontalLayout_23->addWidget(comboSelectSyntax);
+
+
+ verticalLayout_15->addLayout(horizontalLayout_23);
+
+ line_14 = new QFrame(tab_clipboard);
+ line_14->setObjectName(QString::fromUtf8("line_14"));
+ line_14->setFrameShape(QFrame::HLine);
+ line_14->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_15->addWidget(line_14);
+
+ pbCopyToCP = new QPushButton(tab_clipboard);
+ pbCopyToCP->setObjectName(QString::fromUtf8("pbCopyToCP"));
+ pbCopyToCP->setFont(font);
+
+ verticalLayout_15->addWidget(pbCopyToCP);
+
+ verticalSpacer_12 = new QSpacerItem(20, 106, QSizePolicy::Minimum, QSizePolicy::Expanding);
+
+ verticalLayout_15->addItem(verticalSpacer_12);
+
+ tabIOSelection->addTab(tab_clipboard, QString());
+
+ verticalLayout_7->addWidget(tabIOSelection);
+
+ line_7 = new QFrame(centralWidget);
+ line_7->setObjectName(QString::fromUtf8("line_7"));
+ line_7->setFrameShape(QFrame::HLine);
+ line_7->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_7->addWidget(line_7);
+
+ tabWidget = new QTabWidget(centralWidget);
+ tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
+ QSizePolicy sizePolicy5(QSizePolicy::Preferred, QSizePolicy::Minimum);
+ sizePolicy5.setHorizontalStretch(0);
+ sizePolicy5.setVerticalStretch(0);
+ sizePolicy5.setHeightForWidth(tabWidget->sizePolicy().hasHeightForWidth());
+ tabWidget->setSizePolicy(sizePolicy5);
+ tabWidget->setMinimumSize(QSize(0, 0));
+ tabWidget->setLayoutDirection(Qt::LeftToRight);
+ tabWidget->setTabPosition(QTabWidget::North);
+ tabWidget->setTabShape(QTabWidget::Rounded);
+ page_general = new QWidget();
+ page_general->setObjectName(QString::fromUtf8("page_general"));
+ verticalLayout_2 = new QVBoxLayout(page_general);
+ verticalLayout_2->setSpacing(6);
+ verticalLayout_2->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
+ horizontalLayout_8 = new QHBoxLayout();
+ horizontalLayout_8->setSpacing(6);
+ horizontalLayout_8->setObjectName(QString::fromUtf8("horizontalLayout_8"));
+ label_2 = new QLabel(page_general);
+ label_2->setObjectName(QString::fromUtf8("label_2"));
+ QSizePolicy sizePolicy6(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ sizePolicy6.setHorizontalStretch(0);
+ sizePolicy6.setVerticalStretch(0);
+ sizePolicy6.setHeightForWidth(label_2->sizePolicy().hasHeightForWidth());
+ label_2->setSizePolicy(sizePolicy6);
+ label_2->setFont(font);
+
+ horizontalLayout_8->addWidget(label_2);
+
+ comboFormat = new QComboBox(page_general);
+ comboFormat->setObjectName(QString::fromUtf8("comboFormat"));
+ sizePolicy4.setHeightForWidth(comboFormat->sizePolicy().hasHeightForWidth());
+ comboFormat->setSizePolicy(sizePolicy4);
+ comboFormat->setFont(font);
+
+ horizontalLayout_8->addWidget(comboFormat);
+
+
+ verticalLayout_2->addLayout(horizontalLayout_8);
+
+ line_9 = new QFrame(page_general);
+ line_9->setObjectName(QString::fromUtf8("line_9"));
+ line_9->setFrameShape(QFrame::HLine);
+ line_9->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_2->addWidget(line_9);
+
+ horizontalLayout_21 = new QHBoxLayout();
+ horizontalLayout_21->setSpacing(6);
+ horizontalLayout_21->setObjectName(QString::fromUtf8("horizontalLayout_21"));
+ cbIncLineNo = new QCheckBox(page_general);
+ cbIncLineNo->setObjectName(QString::fromUtf8("cbIncLineNo"));
+
+ horizontalLayout_21->addWidget(cbIncLineNo);
+
+ horizontalSpacer_4 = new QSpacerItem(10, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ horizontalLayout_21->addItem(horizontalSpacer_4);
+
+ sbLineNoWidth = new QSpinBox(page_general);
+ sbLineNoWidth->setObjectName(QString::fromUtf8("sbLineNoWidth"));
+ sbLineNoWidth->setMinimum(1);
+ sbLineNoWidth->setMaximum(6);
+ sbLineNoWidth->setValue(2);
+
+ horizontalLayout_21->addWidget(sbLineNoWidth);
+
+
+ verticalLayout_2->addLayout(horizontalLayout_21);
+
+ cbPadZeroes = new QCheckBox(page_general);
+ cbPadZeroes->setObjectName(QString::fromUtf8("cbPadZeroes"));
+ cbPadZeroes->setEnabled(false);
+
+ verticalLayout_2->addWidget(cbPadZeroes);
+
+ cbFragment = new QCheckBox(page_general);
+ cbFragment->setObjectName(QString::fromUtf8("cbFragment"));
+ QSizePolicy sizePolicy7(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ sizePolicy7.setHorizontalStretch(0);
+ sizePolicy7.setVerticalStretch(0);
+ sizePolicy7.setHeightForWidth(cbFragment->sizePolicy().hasHeightForWidth());
+ cbFragment->setSizePolicy(sizePolicy7);
+
+ verticalLayout_2->addWidget(cbFragment);
+
+ cbValidateInput = new QCheckBox(page_general);
+ cbValidateInput->setObjectName(QString::fromUtf8("cbValidateInput"));
+
+ verticalLayout_2->addWidget(cbValidateInput);
+
+ horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setSpacing(6);
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
+ cbEncoding = new QCheckBox(page_general);
+ cbEncoding->setObjectName(QString::fromUtf8("cbEncoding"));
+
+ horizontalLayout_2->addWidget(cbEncoding);
+
+ comboEncoding = new QComboBox(page_general);
+ comboEncoding->setObjectName(QString::fromUtf8("comboEncoding"));
+ comboEncoding->setEditable(true);
+ comboEncoding->setInsertPolicy(QComboBox::InsertAtBottom);
+
+ horizontalLayout_2->addWidget(comboEncoding);
+
+
+ verticalLayout_2->addLayout(horizontalLayout_2);
+
+ verticalSpacer_2 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
+
+ verticalLayout_2->addItem(verticalSpacer_2);
+
+ tabWidget->addTab(page_general, QString());
+ page_output_spec = new QWidget();
+ page_output_spec->setObjectName(QString::fromUtf8("page_output_spec"));
+ gridLayout = new QGridLayout(page_output_spec);
+ gridLayout->setSpacing(6);
+ gridLayout->setContentsMargins(11, 11, 11, 11);
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+ stackedSpecificOptions = new QStackedWidget(page_output_spec);
+ stackedSpecificOptions->setObjectName(QString::fromUtf8("stackedSpecificOptions"));
+ QSizePolicy sizePolicy8(QSizePolicy::Preferred, QSizePolicy::Ignored);
+ sizePolicy8.setHorizontalStretch(0);
+ sizePolicy8.setVerticalStretch(0);
+ sizePolicy8.setHeightForWidth(stackedSpecificOptions->sizePolicy().hasHeightForWidth());
+ stackedSpecificOptions->setSizePolicy(sizePolicy8);
+ stackedSpecificOptions->setMinimumSize(QSize(0, 0));
+ HTMLOptions = new QWidget();
+ HTMLOptions->setObjectName(QString::fromUtf8("HTMLOptions"));
+ verticalLayout_5 = new QVBoxLayout(HTMLOptions);
+ verticalLayout_5->setSpacing(6);
+ verticalLayout_5->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_5->setObjectName(QString::fromUtf8("verticalLayout_5"));
+ label_17 = new QLabel(HTMLOptions);
+ label_17->setObjectName(QString::fromUtf8("label_17"));
+ sizePolicy4.setHeightForWidth(label_17->sizePolicy().hasHeightForWidth());
+ label_17->setSizePolicy(sizePolicy4);
+ label_17->setFont(font);
+
+ verticalLayout_5->addWidget(label_17);
+
+ line_12 = new QFrame(HTMLOptions);
+ line_12->setObjectName(QString::fromUtf8("line_12"));
+ line_12->setFrameShape(QFrame::HLine);
+ line_12->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_5->addWidget(line_12);
+
+ tabWidget1 = new QTabWidget(HTMLOptions);
+ tabWidget1->setObjectName(QString::fromUtf8("tabWidget1"));
+ sizePolicy6.setHeightForWidth(tabWidget1->sizePolicy().hasHeightForWidth());
+ tabWidget1->setSizePolicy(sizePolicy6);
+ tabWidget1->setMinimumSize(QSize(250, 0));
+ tabWidgetPage1 = new QWidget();
+ tabWidgetPage1->setObjectName(QString::fromUtf8("tabWidgetPage1"));
+ gridLayout_4 = new QGridLayout(tabWidgetPage1);
+ gridLayout_4->setSpacing(6);
+ gridLayout_4->setContentsMargins(11, 11, 11, 11);
+ gridLayout_4->setObjectName(QString::fromUtf8("gridLayout_4"));
+ horizontalLayout_10 = new QHBoxLayout();
+ horizontalLayout_10->setSpacing(6);
+ horizontalLayout_10->setObjectName(QString::fromUtf8("horizontalLayout_10"));
+ cbHTMLEmbedStyle = new QCheckBox(tabWidgetPage1);
+ cbHTMLEmbedStyle->setObjectName(QString::fromUtf8("cbHTMLEmbedStyle"));
+
+ horizontalLayout_10->addWidget(cbHTMLEmbedStyle);
+
+ cbHTMLInlineCSS = new QCheckBox(tabWidgetPage1);
+ cbHTMLInlineCSS->setObjectName(QString::fromUtf8("cbHTMLInlineCSS"));
+ cbHTMLInlineCSS->setEnabled(false);
+ cbHTMLInlineCSS->setCheckable(true);
+
+ horizontalLayout_10->addWidget(cbHTMLInlineCSS);
+
+
+ gridLayout_4->addLayout(horizontalLayout_10, 0, 0, 1, 1);
+
+ horizontalLayout_14 = new QHBoxLayout();
+ horizontalLayout_14->setSpacing(6);
+ horizontalLayout_14->setObjectName(QString::fromUtf8("horizontalLayout_14"));
+ label_19 = new QLabel(tabWidgetPage1);
+ label_19->setObjectName(QString::fromUtf8("label_19"));
+
+ horizontalLayout_14->addWidget(label_19);
+
+ leHTMLStyleFile = new QLineEdit(tabWidgetPage1);
+ leHTMLStyleFile->setObjectName(QString::fromUtf8("leHTMLStyleFile"));
+ sizePolicy4.setHeightForWidth(leHTMLStyleFile->sizePolicy().hasHeightForWidth());
+ leHTMLStyleFile->setSizePolicy(sizePolicy4);
+
+ horizontalLayout_14->addWidget(leHTMLStyleFile);
+
+
+ gridLayout_4->addLayout(horizontalLayout_14, 1, 0, 1, 1);
+
+ horizontalLayout_9 = new QHBoxLayout();
+ horizontalLayout_9->setSpacing(6);
+ horizontalLayout_9->setObjectName(QString::fromUtf8("horizontalLayout_9"));
+ label_20 = new QLabel(tabWidgetPage1);
+ label_20->setObjectName(QString::fromUtf8("label_20"));
+
+ horizontalLayout_9->addWidget(label_20);
+
+ leHTMLStyleIncFile = new QLineEdit(tabWidgetPage1);
+ leHTMLStyleIncFile->setObjectName(QString::fromUtf8("leHTMLStyleIncFile"));
+
+ horizontalLayout_9->addWidget(leHTMLStyleIncFile);
+
+ pbHTMLChooseStyleIncFile = new QPushButton(tabWidgetPage1);
+ pbHTMLChooseStyleIncFile->setObjectName(QString::fromUtf8("pbHTMLChooseStyleIncFile"));
+
+ horizontalLayout_9->addWidget(pbHTMLChooseStyleIncFile);
+
+
+ gridLayout_4->addLayout(horizontalLayout_9, 2, 0, 1, 1);
+
+ horizontalLayout_7 = new QHBoxLayout();
+ horizontalLayout_7->setSpacing(6);
+ horizontalLayout_7->setObjectName(QString::fromUtf8("horizontalLayout_7"));
+ label = new QLabel(tabWidgetPage1);
+ label->setObjectName(QString::fromUtf8("label"));
+
+ horizontalLayout_7->addWidget(label);
+
+ leHTMLCssPrefix = new QLineEdit(tabWidgetPage1);
+ leHTMLCssPrefix->setObjectName(QString::fromUtf8("leHTMLCssPrefix"));
+
+ horizontalLayout_7->addWidget(leHTMLCssPrefix);
+
+
+ gridLayout_4->addLayout(horizontalLayout_7, 3, 0, 1, 1);
+
+ verticalSpacer_9 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);
+
+ gridLayout_4->addItem(verticalSpacer_9, 4, 0, 1, 1);
+
+ tabWidget1->addTab(tabWidgetPage1, QString());
+ tabWidgetPage2 = new QWidget();
+ tabWidgetPage2->setObjectName(QString::fromUtf8("tabWidgetPage2"));
+ verticalLayout_6 = new QVBoxLayout(tabWidgetPage2);
+ verticalLayout_6->setSpacing(6);
+ verticalLayout_6->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_6->setObjectName(QString::fromUtf8("verticalLayout_6"));
+ cbHTMLIndex = new QCheckBox(tabWidgetPage2);
+ cbHTMLIndex->setObjectName(QString::fromUtf8("cbHTMLIndex"));
+
+ verticalLayout_6->addWidget(cbHTMLIndex);
+
+ line_13 = new QFrame(tabWidgetPage2);
+ line_13->setObjectName(QString::fromUtf8("line_13"));
+ line_13->setFrameShape(QFrame::HLine);
+ line_13->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_6->addWidget(line_13);
+
+ cbHTMLCtags = new QCheckBox(tabWidgetPage2);
+ cbHTMLCtags->setObjectName(QString::fromUtf8("cbHTMLCtags"));
+ sizePolicy7.setHeightForWidth(cbHTMLCtags->sizePolicy().hasHeightForWidth());
+ cbHTMLCtags->setSizePolicy(sizePolicy7);
+
+ verticalLayout_6->addWidget(cbHTMLCtags);
+
+ horizontalLayout_12 = new QHBoxLayout();
+ horizontalLayout_12->setSpacing(6);
+ horizontalLayout_12->setObjectName(QString::fromUtf8("horizontalLayout_12"));
+ leHTMLCtagsFile = new QLineEdit(tabWidgetPage2);
+ leHTMLCtagsFile->setObjectName(QString::fromUtf8("leHTMLCtagsFile"));
+ QSizePolicy sizePolicy9(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ sizePolicy9.setHorizontalStretch(0);
+ sizePolicy9.setVerticalStretch(0);
+ sizePolicy9.setHeightForWidth(leHTMLCtagsFile->sizePolicy().hasHeightForWidth());
+ leHTMLCtagsFile->setSizePolicy(sizePolicy9);
+
+ horizontalLayout_12->addWidget(leHTMLCtagsFile);
+
+ pbHTMLChooseTagsFile = new QPushButton(tabWidgetPage2);
+ pbHTMLChooseTagsFile->setObjectName(QString::fromUtf8("pbHTMLChooseTagsFile"));
+ sizePolicy3.setHeightForWidth(pbHTMLChooseTagsFile->sizePolicy().hasHeightForWidth());
+ pbHTMLChooseTagsFile->setSizePolicy(sizePolicy3);
+
+ horizontalLayout_12->addWidget(pbHTMLChooseTagsFile);
+
+
+ verticalLayout_6->addLayout(horizontalLayout_12);
+
+ verticalSpacer_8 = new QSpacerItem(20, 72, QSizePolicy::Minimum, QSizePolicy::Expanding);
+
+ verticalLayout_6->addItem(verticalSpacer_8);
+
+ tabWidget1->addTab(tabWidgetPage2, QString());
+ tabWidgetPage3 = new QWidget();
+ tabWidgetPage3->setObjectName(QString::fromUtf8("tabWidgetPage3"));
+ verticalLayout_4 = new QVBoxLayout(tabWidgetPage3);
+ verticalLayout_4->setSpacing(6);
+ verticalLayout_4->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_4->setObjectName(QString::fromUtf8("verticalLayout_4"));
+ label_8 = new QLabel(tabWidgetPage3);
+ label_8->setObjectName(QString::fromUtf8("label_8"));
+ QFont font2;
+ font2.setBold(false);
+ font2.setWeight(50);
+ label_8->setFont(font2);
+
+ verticalLayout_4->addWidget(label_8);
+
+ cbHTMLAnchors = new QCheckBox(tabWidgetPage3);
+ cbHTMLAnchors->setObjectName(QString::fromUtf8("cbHTMLAnchors"));
+
+ verticalLayout_4->addWidget(cbHTMLAnchors);
+
+ cbHTMLFileNameAnchor = new QCheckBox(tabWidgetPage3);
+ cbHTMLFileNameAnchor->setObjectName(QString::fromUtf8("cbHTMLFileNameAnchor"));
+
+ verticalLayout_4->addWidget(cbHTMLFileNameAnchor);
+
+ cbHTMLOrderedList = new QCheckBox(tabWidgetPage3);
+ cbHTMLOrderedList->setObjectName(QString::fromUtf8("cbHTMLOrderedList"));
+
+ verticalLayout_4->addWidget(cbHTMLOrderedList);
+
+ line_4 = new QFrame(tabWidgetPage3);
+ line_4->setObjectName(QString::fromUtf8("line_4"));
+ line_4->setFrameShape(QFrame::HLine);
+ line_4->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_4->addWidget(line_4);
+
+ cbHTMLEnclosePreTags = new QCheckBox(tabWidgetPage3);
+ cbHTMLEnclosePreTags->setObjectName(QString::fromUtf8("cbHTMLEnclosePreTags"));
+
+ verticalLayout_4->addWidget(cbHTMLEnclosePreTags);
+
+ verticalSpacer = new QSpacerItem(20, 24, QSizePolicy::Minimum, QSizePolicy::Expanding);
+
+ verticalLayout_4->addItem(verticalSpacer);
+
+ tabWidget1->addTab(tabWidgetPage3, QString());
+
+ verticalLayout_5->addWidget(tabWidget1);
+
+ stackedSpecificOptions->addWidget(HTMLOptions);
+ LATEXOptions = new QWidget();
+ LATEXOptions->setObjectName(QString::fromUtf8("LATEXOptions"));
+ verticalLayout_12 = new QVBoxLayout(LATEXOptions);
+ verticalLayout_12->setSpacing(6);
+ verticalLayout_12->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_12->setObjectName(QString::fromUtf8("verticalLayout_12"));
+ label_18 = new QLabel(LATEXOptions);
+ label_18->setObjectName(QString::fromUtf8("label_18"));
+ QSizePolicy sizePolicy10(QSizePolicy::Maximum, QSizePolicy::Preferred);
+ sizePolicy10.setHorizontalStretch(0);
+ sizePolicy10.setVerticalStretch(0);
+ sizePolicy10.setHeightForWidth(label_18->sizePolicy().hasHeightForWidth());
+ label_18->setSizePolicy(sizePolicy10);
+ label_18->setFont(font);
+
+ verticalLayout_12->addWidget(label_18);
+
+ line_8 = new QFrame(LATEXOptions);
+ line_8->setObjectName(QString::fromUtf8("line_8"));
+ line_8->setFrameShape(QFrame::HLine);
+ line_8->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_12->addWidget(line_8);
+
+ cbLATEXEscQuotes = new QCheckBox(LATEXOptions);
+ cbLATEXEscQuotes->setObjectName(QString::fromUtf8("cbLATEXEscQuotes"));
+
+ verticalLayout_12->addWidget(cbLATEXEscQuotes);
+
+ cbLATEXBabel = new QCheckBox(LATEXOptions);
+ cbLATEXBabel->setObjectName(QString::fromUtf8("cbLATEXBabel"));
+
+ verticalLayout_12->addWidget(cbLATEXBabel);
+
+ cbLATEXPrettySymbols = new QCheckBox(LATEXOptions);
+ cbLATEXPrettySymbols->setObjectName(QString::fromUtf8("cbLATEXPrettySymbols"));
+
+ verticalLayout_12->addWidget(cbLATEXPrettySymbols);
+
+ cbLATEXEmbedStyle = new QCheckBox(LATEXOptions);
+ cbLATEXEmbedStyle->setObjectName(QString::fromUtf8("cbLATEXEmbedStyle"));
+
+ verticalLayout_12->addWidget(cbLATEXEmbedStyle);
+
+ horizontalLayout_17 = new QHBoxLayout();
+ horizontalLayout_17->setSpacing(6);
+ horizontalLayout_17->setObjectName(QString::fromUtf8("horizontalLayout_17"));
+ label_21 = new QLabel(LATEXOptions);
+ label_21->setObjectName(QString::fromUtf8("label_21"));
+
+ horizontalLayout_17->addWidget(label_21);
+
+ leLATEXStyleFile = new QLineEdit(LATEXOptions);
+ leLATEXStyleFile->setObjectName(QString::fromUtf8("leLATEXStyleFile"));
+
+ horizontalLayout_17->addWidget(leLATEXStyleFile);
+
+
+ verticalLayout_12->addLayout(horizontalLayout_17);
+
+ horizontalLayout_15 = new QHBoxLayout();
+ horizontalLayout_15->setSpacing(6);
+ horizontalLayout_15->setObjectName(QString::fromUtf8("horizontalLayout_15"));
+ label_22 = new QLabel(LATEXOptions);
+ label_22->setObjectName(QString::fromUtf8("label_22"));
+
+ horizontalLayout_15->addWidget(label_22);
+
+ horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ horizontalLayout_15->addItem(horizontalSpacer_2);
+
+
+ verticalLayout_12->addLayout(horizontalLayout_15);
+
+ horizontalLayout_16 = new QHBoxLayout();
+ horizontalLayout_16->setSpacing(6);
+ horizontalLayout_16->setObjectName(QString::fromUtf8("horizontalLayout_16"));
+ leLATEXStyleIncFile = new QLineEdit(LATEXOptions);
+ leLATEXStyleIncFile->setObjectName(QString::fromUtf8("leLATEXStyleIncFile"));
+
+ horizontalLayout_16->addWidget(leLATEXStyleIncFile);
+
+ pbLATEXChooseStyleIncFile = new QPushButton(LATEXOptions);
+ pbLATEXChooseStyleIncFile->setObjectName(QString::fromUtf8("pbLATEXChooseStyleIncFile"));
+
+ horizontalLayout_16->addWidget(pbLATEXChooseStyleIncFile);
+
+
+ verticalLayout_12->addLayout(horizontalLayout_16);
+
+ verticalSpacer_4 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
+
+ verticalLayout_12->addItem(verticalSpacer_4);
+
+ stackedSpecificOptions->addWidget(LATEXOptions);
+ TEXOptions = new QWidget();
+ TEXOptions->setObjectName(QString::fromUtf8("TEXOptions"));
+ verticalLayout_14 = new QVBoxLayout(TEXOptions);
+ verticalLayout_14->setSpacing(6);
+ verticalLayout_14->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_14->setObjectName(QString::fromUtf8("verticalLayout_14"));
+ label_26 = new QLabel(TEXOptions);
+ label_26->setObjectName(QString::fromUtf8("label_26"));
+ sizePolicy4.setHeightForWidth(label_26->sizePolicy().hasHeightForWidth());
+ label_26->setSizePolicy(sizePolicy4);
+ label_26->setFont(font);
+
+ verticalLayout_14->addWidget(label_26);
+
+ line_10 = new QFrame(TEXOptions);
+ line_10->setObjectName(QString::fromUtf8("line_10"));
+ line_10->setFrameShape(QFrame::HLine);
+ line_10->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_14->addWidget(line_10);
+
+ cbTEXEmbedStyle = new QCheckBox(TEXOptions);
+ cbTEXEmbedStyle->setObjectName(QString::fromUtf8("cbTEXEmbedStyle"));
+
+ verticalLayout_14->addWidget(cbTEXEmbedStyle);
+
+ horizontalLayout_18 = new QHBoxLayout();
+ horizontalLayout_18->setSpacing(6);
+ horizontalLayout_18->setObjectName(QString::fromUtf8("horizontalLayout_18"));
+ label_24 = new QLabel(TEXOptions);
+ label_24->setObjectName(QString::fromUtf8("label_24"));
+
+ horizontalLayout_18->addWidget(label_24);
+
+ leTEXStyleFile = new QLineEdit(TEXOptions);
+ leTEXStyleFile->setObjectName(QString::fromUtf8("leTEXStyleFile"));
+
+ horizontalLayout_18->addWidget(leTEXStyleFile);
+
+
+ verticalLayout_14->addLayout(horizontalLayout_18);
+
+ horizontalLayout_19 = new QHBoxLayout();
+ horizontalLayout_19->setSpacing(6);
+ horizontalLayout_19->setObjectName(QString::fromUtf8("horizontalLayout_19"));
+ label_25 = new QLabel(TEXOptions);
+ label_25->setObjectName(QString::fromUtf8("label_25"));
+
+ horizontalLayout_19->addWidget(label_25);
+
+ horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ horizontalLayout_19->addItem(horizontalSpacer_3);
+
+
+ verticalLayout_14->addLayout(horizontalLayout_19);
+
+ horizontalLayout_20 = new QHBoxLayout();
+ horizontalLayout_20->setSpacing(6);
+ horizontalLayout_20->setObjectName(QString::fromUtf8("horizontalLayout_20"));
+ leTEXStyleIncFile = new QLineEdit(TEXOptions);
+ leTEXStyleIncFile->setObjectName(QString::fromUtf8("leTEXStyleIncFile"));
+
+ horizontalLayout_20->addWidget(leTEXStyleIncFile);
+
+ pbTEXChooseStyleIncFile = new QPushButton(TEXOptions);
+ pbTEXChooseStyleIncFile->setObjectName(QString::fromUtf8("pbTEXChooseStyleIncFile"));
+
+ horizontalLayout_20->addWidget(pbTEXChooseStyleIncFile);
+
+
+ verticalLayout_14->addLayout(horizontalLayout_20);
+
+ verticalSpacer_5 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
+
+ verticalLayout_14->addItem(verticalSpacer_5);
+
+ stackedSpecificOptions->addWidget(TEXOptions);
+ RTFOptions = new QWidget();
+ RTFOptions->setObjectName(QString::fromUtf8("RTFOptions"));
+ verticalLayout_9 = new QVBoxLayout(RTFOptions);
+ verticalLayout_9->setSpacing(6);
+ verticalLayout_9->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_9->setObjectName(QString::fromUtf8("verticalLayout_9"));
+ label_15 = new QLabel(RTFOptions);
+ label_15->setObjectName(QString::fromUtf8("label_15"));
+ sizePolicy4.setHeightForWidth(label_15->sizePolicy().hasHeightForWidth());
+ label_15->setSizePolicy(sizePolicy4);
+ label_15->setFont(font);
+
+ verticalLayout_9->addWidget(label_15);
+
+ line_5 = new QFrame(RTFOptions);
+ line_5->setObjectName(QString::fromUtf8("line_5"));
+ line_5->setFrameShape(QFrame::HLine);
+ line_5->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_9->addWidget(line_5);
+
+ cbRTFCharStyles = new QCheckBox(RTFOptions);
+ cbRTFCharStyles->setObjectName(QString::fromUtf8("cbRTFCharStyles"));
+
+ verticalLayout_9->addWidget(cbRTFCharStyles);
+
+ horizontalLayout_11 = new QHBoxLayout();
+ horizontalLayout_11->setSpacing(6);
+ horizontalLayout_11->setObjectName(QString::fromUtf8("horizontalLayout_11"));
+ label_9 = new QLabel(RTFOptions);
+ label_9->setObjectName(QString::fromUtf8("label_9"));
+
+ horizontalLayout_11->addWidget(label_9);
+
+ comboRTFPageSize = new QComboBox(RTFOptions);
+ comboRTFPageSize->setObjectName(QString::fromUtf8("comboRTFPageSize"));
+
+ horizontalLayout_11->addWidget(comboRTFPageSize);
+
+
+ verticalLayout_9->addLayout(horizontalLayout_11);
+
+ verticalSpacer_6 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
+
+ verticalLayout_9->addItem(verticalSpacer_6);
+
+ stackedSpecificOptions->addWidget(RTFOptions);
+ SVGOptions = new QWidget();
+ SVGOptions->setObjectName(QString::fromUtf8("SVGOptions"));
+ verticalLayout_10 = new QVBoxLayout(SVGOptions);
+ verticalLayout_10->setSpacing(6);
+ verticalLayout_10->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_10->setObjectName(QString::fromUtf8("verticalLayout_10"));
+ label_16 = new QLabel(SVGOptions);
+ label_16->setObjectName(QString::fromUtf8("label_16"));
+ sizePolicy4.setHeightForWidth(label_16->sizePolicy().hasHeightForWidth());
+ label_16->setSizePolicy(sizePolicy4);
+ label_16->setFont(font);
+
+ verticalLayout_10->addWidget(label_16);
+
+ line_6 = new QFrame(SVGOptions);
+ line_6->setObjectName(QString::fromUtf8("line_6"));
+ line_6->setFrameShape(QFrame::HLine);
+ line_6->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_10->addWidget(line_6);
+
+ label_10 = new QLabel(SVGOptions);
+ label_10->setObjectName(QString::fromUtf8("label_10"));
+
+ verticalLayout_10->addWidget(label_10);
+
+ gridLayout_8 = new QGridLayout();
+ gridLayout_8->setSpacing(6);
+ gridLayout_8->setObjectName(QString::fromUtf8("gridLayout_8"));
+ label_3 = new QLabel(SVGOptions);
+ label_3->setObjectName(QString::fromUtf8("label_3"));
+
+ gridLayout_8->addWidget(label_3, 0, 0, 1, 1);
+
+ leSVGWidth = new QLineEdit(SVGOptions);
+ leSVGWidth->setObjectName(QString::fromUtf8("leSVGWidth"));
+
+ gridLayout_8->addWidget(leSVGWidth, 0, 1, 1, 1);
+
+ label_12 = new QLabel(SVGOptions);
+ label_12->setObjectName(QString::fromUtf8("label_12"));
+
+ gridLayout_8->addWidget(label_12, 1, 0, 1, 1);
+
+ leSVGHeight = new QLineEdit(SVGOptions);
+ leSVGHeight->setObjectName(QString::fromUtf8("leSVGHeight"));
+
+ gridLayout_8->addWidget(leSVGHeight, 1, 1, 1, 1);
+
+
+ verticalLayout_10->addLayout(gridLayout_8);
+
+ cbSVGEmbedStyle = new QCheckBox(SVGOptions);
+ cbSVGEmbedStyle->setObjectName(QString::fromUtf8("cbSVGEmbedStyle"));
+
+ verticalLayout_10->addWidget(cbSVGEmbedStyle);
+
+ horizontalLayout_26 = new QHBoxLayout();
+ horizontalLayout_26->setSpacing(6);
+ horizontalLayout_26->setObjectName(QString::fromUtf8("horizontalLayout_26"));
+ label_29 = new QLabel(SVGOptions);
+ label_29->setObjectName(QString::fromUtf8("label_29"));
+
+ horizontalLayout_26->addWidget(label_29);
+
+ leSVGStyleFile = new QLineEdit(SVGOptions);
+ leSVGStyleFile->setObjectName(QString::fromUtf8("leSVGStyleFile"));
+
+ horizontalLayout_26->addWidget(leSVGStyleFile);
+
+
+ verticalLayout_10->addLayout(horizontalLayout_26);
+
+ horizontalLayout_27 = new QHBoxLayout();
+ horizontalLayout_27->setSpacing(6);
+ horizontalLayout_27->setObjectName(QString::fromUtf8("horizontalLayout_27"));
+ label_30 = new QLabel(SVGOptions);
+ label_30->setObjectName(QString::fromUtf8("label_30"));
+
+ horizontalLayout_27->addWidget(label_30);
+
+ horizontalSpacer_6 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ horizontalLayout_27->addItem(horizontalSpacer_6);
+
+
+ verticalLayout_10->addLayout(horizontalLayout_27);
+
+ horizontalLayout_28 = new QHBoxLayout();
+ horizontalLayout_28->setSpacing(6);
+ horizontalLayout_28->setObjectName(QString::fromUtf8("horizontalLayout_28"));
+ leSVGStyleIncFile = new QLineEdit(SVGOptions);
+ leSVGStyleIncFile->setObjectName(QString::fromUtf8("leSVGStyleIncFile"));
+
+ horizontalLayout_28->addWidget(leSVGStyleIncFile);
+
+ pbSVGChooseStyleIncFile = new QPushButton(SVGOptions);
+ pbSVGChooseStyleIncFile->setObjectName(QString::fromUtf8("pbSVGChooseStyleIncFile"));
+
+ horizontalLayout_28->addWidget(pbSVGChooseStyleIncFile);
+
+
+ verticalLayout_10->addLayout(horizontalLayout_28);
+
+ verticalSpacer_10 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
+
+ verticalLayout_10->addItem(verticalSpacer_10);
+
+ stackedSpecificOptions->addWidget(SVGOptions);
+ EmptyPage = new QWidget();
+ EmptyPage->setObjectName(QString::fromUtf8("EmptyPage"));
+ verticalLayout_11 = new QVBoxLayout(EmptyPage);
+ verticalLayout_11->setSpacing(6);
+ verticalLayout_11->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_11->setObjectName(QString::fromUtf8("verticalLayout_11"));
+ label_7 = new QLabel(EmptyPage);
+ label_7->setObjectName(QString::fromUtf8("label_7"));
+
+ verticalLayout_11->addWidget(label_7);
+
+ verticalSpacer_3 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
+
+ verticalLayout_11->addItem(verticalSpacer_3);
+
+ stackedSpecificOptions->addWidget(EmptyPage);
+
+ gridLayout->addWidget(stackedSpecificOptions, 0, 0, 1, 1);
+
+ tabWidget->addTab(page_output_spec, QString());
+ page_formatting = new QWidget();
+ page_formatting->setObjectName(QString::fromUtf8("page_formatting"));
+ verticalLayout_8 = new QVBoxLayout(page_formatting);
+ verticalLayout_8->setSpacing(6);
+ verticalLayout_8->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_8->setObjectName(QString::fromUtf8("verticalLayout_8"));
+ horizontalLayout_3 = new QHBoxLayout();
+ horizontalLayout_3->setSpacing(6);
+ horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
+ label_5 = new QLabel(page_formatting);
+ label_5->setObjectName(QString::fromUtf8("label_5"));
+ sizePolicy6.setHeightForWidth(label_5->sizePolicy().hasHeightForWidth());
+ label_5->setSizePolicy(sizePolicy6);
+
+ horizontalLayout_3->addWidget(label_5);
+
+ comboTheme = new QComboBox(page_formatting);
+ comboTheme->setObjectName(QString::fromUtf8("comboTheme"));
+ sizePolicy7.setHeightForWidth(comboTheme->sizePolicy().hasHeightForWidth());
+ comboTheme->setSizePolicy(sizePolicy7);
+
+ horizontalLayout_3->addWidget(comboTheme);
+
+
+ verticalLayout_8->addLayout(horizontalLayout_3);
+
+ horizontalLayout_4 = new QHBoxLayout();
+ horizontalLayout_4->setSpacing(6);
+ horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4"));
+ cbReformat = new QCheckBox(page_formatting);
+ cbReformat->setObjectName(QString::fromUtf8("cbReformat"));
+
+ horizontalLayout_4->addWidget(cbReformat);
+
+ comboReformat = new QComboBox(page_formatting);
+ comboReformat->setObjectName(QString::fromUtf8("comboReformat"));
+ sizePolicy7.setHeightForWidth(comboReformat->sizePolicy().hasHeightForWidth());
+ comboReformat->setSizePolicy(sizePolicy7);
+
+ horizontalLayout_4->addWidget(comboReformat);
+
+
+ verticalLayout_8->addLayout(horizontalLayout_4);
+
+ horizontalLayout_5 = new QHBoxLayout();
+ horizontalLayout_5->setSpacing(6);
+ horizontalLayout_5->setObjectName(QString::fromUtf8("horizontalLayout_5"));
+ cbKwCase = new QCheckBox(page_formatting);
+ cbKwCase->setObjectName(QString::fromUtf8("cbKwCase"));
+
+ horizontalLayout_5->addWidget(cbKwCase);
+
+ comboKwCase = new QComboBox(page_formatting);
+ comboKwCase->setObjectName(QString::fromUtf8("comboKwCase"));
+ sizePolicy7.setHeightForWidth(comboKwCase->sizePolicy().hasHeightForWidth());
+ comboKwCase->setSizePolicy(sizePolicy7);
+
+ horizontalLayout_5->addWidget(comboKwCase);
+
+
+ verticalLayout_8->addLayout(horizontalLayout_5);
+
+ horizontalLayout_6 = new QHBoxLayout();
+ horizontalLayout_6->setSpacing(6);
+ horizontalLayout_6->setObjectName(QString::fromUtf8("horizontalLayout_6"));
+ label_6 = new QLabel(page_formatting);
+ label_6->setObjectName(QString::fromUtf8("label_6"));
+ sizePolicy7.setHeightForWidth(label_6->sizePolicy().hasHeightForWidth());
+ label_6->setSizePolicy(sizePolicy7);
+
+ horizontalLayout_6->addWidget(label_6);
+
+ sbTabWidth = new QSpinBox(page_formatting);
+ sbTabWidth->setObjectName(QString::fromUtf8("sbTabWidth"));
+ sbTabWidth->setMaximum(10);
+
+ horizontalLayout_6->addWidget(sbTabWidth);
+
+
+ verticalLayout_8->addLayout(horizontalLayout_6);
+
+ gridLayout_2 = new QGridLayout();
+ gridLayout_2->setSpacing(6);
+ gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
+ cbWrapping = new QCheckBox(page_formatting);
+ cbWrapping->setObjectName(QString::fromUtf8("cbWrapping"));
+
+ gridLayout_2->addWidget(cbWrapping, 0, 0, 1, 1);
+
+ sbLineLength = new QSpinBox(page_formatting);
+ sbLineLength->setObjectName(QString::fromUtf8("sbLineLength"));
+ sbLineLength->setMinimum(60);
+ sbLineLength->setMaximum(120);
+ sbLineLength->setSingleStep(2);
+
+ gridLayout_2->addWidget(sbLineLength, 0, 1, 1, 1);
+
+ cbAdvWrapping = new QCheckBox(page_formatting);
+ cbAdvWrapping->setObjectName(QString::fromUtf8("cbAdvWrapping"));
+ cbAdvWrapping->setEnabled(false);
+
+ gridLayout_2->addWidget(cbAdvWrapping, 1, 0, 1, 1);
+
+ verticalSpacer_11 = new QSpacerItem(20, 13, QSizePolicy::Minimum, QSizePolicy::Minimum);
+
+ gridLayout_2->addItem(verticalSpacer_11, 1, 1, 1, 1);
+
+
+ verticalLayout_8->addLayout(gridLayout_2);
+
+ line_3 = new QFrame(page_formatting);
+ line_3->setObjectName(QString::fromUtf8("line_3"));
+ line_3->setFrameShape(QFrame::HLine);
+ line_3->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout_8->addWidget(line_3);
+
+ gridLayout_9 = new QGridLayout();
+ gridLayout_9->setSpacing(6);
+ gridLayout_9->setObjectName(QString::fromUtf8("gridLayout_9"));
+ label_23 = new QLabel(page_formatting);
+ label_23->setObjectName(QString::fromUtf8("label_23"));
+
+ gridLayout_9->addWidget(label_23, 0, 0, 1, 1);
+
+ comboFontName = new QFontComboBox(page_formatting);
+ comboFontName->setObjectName(QString::fromUtf8("comboFontName"));
+
+ gridLayout_9->addWidget(comboFontName, 0, 1, 1, 1);
+
+ label_4 = new QLabel(page_formatting);
+ label_4->setObjectName(QString::fromUtf8("label_4"));
+
+ gridLayout_9->addWidget(label_4, 1, 0, 1, 1);
+
+ leFontSize = new QLineEdit(page_formatting);
+ leFontSize->setObjectName(QString::fromUtf8("leFontSize"));
+ sizePolicy4.setHeightForWidth(leFontSize->sizePolicy().hasHeightForWidth());
+ leFontSize->setSizePolicy(sizePolicy4);
+
+ gridLayout_9->addWidget(leFontSize, 1, 1, 1, 1);
+
+
+ verticalLayout_8->addLayout(gridLayout_9);
+
+ tabWidget->addTab(page_formatting, QString());
+
+ verticalLayout_7->addWidget(tabWidget);
+
+
+ horizontalLayout_24->addLayout(verticalLayout_7);
+
+ line = new QFrame(centralWidget);
+ line->setObjectName(QString::fromUtf8("line"));
+ line->setFrameShape(QFrame::VLine);
+ line->setFrameShadow(QFrame::Sunken);
+
+ horizontalLayout_24->addWidget(line);
+
+ verticalLayout_13 = new QVBoxLayout();
+ verticalLayout_13->setSpacing(6);
+ verticalLayout_13->setObjectName(QString::fromUtf8("verticalLayout_13"));
+ lbPreview = new QLabel(centralWidget);
+ lbPreview->setObjectName(QString::fromUtf8("lbPreview"));
+
+ verticalLayout_13->addWidget(lbPreview);
+
+ browserPreview = new QTextBrowser(centralWidget);
+ browserPreview->setObjectName(QString::fromUtf8("browserPreview"));
+ QSizePolicy sizePolicy11(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ sizePolicy11.setHorizontalStretch(0);
+ sizePolicy11.setVerticalStretch(0);
+ sizePolicy11.setHeightForWidth(browserPreview->sizePolicy().hasHeightForWidth());
+ browserPreview->setSizePolicy(sizePolicy11);
+
+ verticalLayout_13->addWidget(browserPreview);
+
+ horizontalLayout_13 = new QHBoxLayout();
+ horizontalLayout_13->setSpacing(6);
+ horizontalLayout_13->setObjectName(QString::fromUtf8("horizontalLayout_13"));
+ label_14 = new QLabel(centralWidget);
+ label_14->setObjectName(QString::fromUtf8("label_14"));
+
+ horizontalLayout_13->addWidget(label_14);
+
+ progressBar = new QProgressBar(centralWidget);
+ progressBar->setObjectName(QString::fromUtf8("progressBar"));
+ progressBar->setValue(0);
+
+ horizontalLayout_13->addWidget(progressBar);
+
+
+ verticalLayout_13->addLayout(horizontalLayout_13);
+
+
+ horizontalLayout_24->addLayout(verticalLayout_13);
+
+ MainWindowClass->setCentralWidget(centralWidget);
+ menuBar = new QMenuBar(MainWindowClass);
+ menuBar->setObjectName(QString::fromUtf8("menuBar"));
+ menuBar->setGeometry(QRect(0, 0, 600, 20));
+ menu_File = new QMenu(menuBar);
+ menu_File->setObjectName(QString::fromUtf8("menu_File"));
+ menu_Help = new QMenu(menuBar);
+ menu_Help->setObjectName(QString::fromUtf8("menu_Help"));
+ MainWindowClass->setMenuBar(menuBar);
+ statusBar = new QStatusBar(MainWindowClass);
+ statusBar->setObjectName(QString::fromUtf8("statusBar"));
+ MainWindowClass->setStatusBar(statusBar);
+#ifndef QT_NO_SHORTCUT
+ label_2->setBuddy(comboFormat);
+ label_21->setBuddy(leLATEXStyleFile);
+ label_24->setBuddy(leTEXStyleFile);
+ label_3->setBuddy(leSVGWidth);
+ label_12->setBuddy(leSVGHeight);
+ label_29->setBuddy(leSVGStyleFile);
+ label_5->setBuddy(comboTheme);
+ label_6->setBuddy(sbTabWidth);
+ label_23->setBuddy(comboFontName);
+ label_4->setBuddy(leFontSize);
+#endif // QT_NO_SHORTCUT
+ QWidget::setTabOrder(pbOpenFiles, lvInputFiles);
+ QWidget::setTabOrder(lvInputFiles, pbClearSelection);
+ QWidget::setTabOrder(pbClearSelection, pbClearAll);
+ QWidget::setTabOrder(pbClearAll, tabWidget);
+ QWidget::setTabOrder(tabWidget, comboFormat);
+ QWidget::setTabOrder(comboFormat, cbIncLineNo);
+ QWidget::setTabOrder(cbIncLineNo, sbLineNoWidth);
+ QWidget::setTabOrder(sbLineNoWidth, cbPadZeroes);
+ QWidget::setTabOrder(cbPadZeroes, cbFragment);
+ QWidget::setTabOrder(cbFragment, cbValidateInput);
+ QWidget::setTabOrder(cbValidateInput, cbEncoding);
+ QWidget::setTabOrder(cbEncoding, comboEncoding);
+ QWidget::setTabOrder(comboEncoding, cbHTMLEmbedStyle);
+ QWidget::setTabOrder(cbHTMLEmbedStyle, cbHTMLInlineCSS);
+ QWidget::setTabOrder(cbHTMLInlineCSS, leHTMLStyleFile);
+ QWidget::setTabOrder(leHTMLStyleFile, leHTMLStyleIncFile);
+ QWidget::setTabOrder(leHTMLStyleIncFile, pbHTMLChooseStyleIncFile);
+ QWidget::setTabOrder(pbHTMLChooseStyleIncFile, leHTMLCssPrefix);
+ QWidget::setTabOrder(leHTMLCssPrefix, cbHTMLIndex);
+ QWidget::setTabOrder(cbHTMLIndex, cbHTMLCtags);
+ QWidget::setTabOrder(cbHTMLCtags, leHTMLCtagsFile);
+ QWidget::setTabOrder(leHTMLCtagsFile, pbHTMLChooseTagsFile);
+ QWidget::setTabOrder(pbHTMLChooseTagsFile, cbHTMLAnchors);
+ QWidget::setTabOrder(cbHTMLAnchors, cbHTMLFileNameAnchor);
+ QWidget::setTabOrder(cbHTMLFileNameAnchor, cbHTMLOrderedList);
+ QWidget::setTabOrder(cbHTMLOrderedList, cbHTMLEnclosePreTags);
+ QWidget::setTabOrder(cbHTMLEnclosePreTags, cbLATEXEscQuotes);
+ QWidget::setTabOrder(cbLATEXEscQuotes, cbLATEXBabel);
+ QWidget::setTabOrder(cbLATEXBabel, cbLATEXPrettySymbols);
+ QWidget::setTabOrder(cbLATEXPrettySymbols, cbLATEXEmbedStyle);
+ QWidget::setTabOrder(cbLATEXEmbedStyle, leLATEXStyleFile);
+ QWidget::setTabOrder(leLATEXStyleFile, leLATEXStyleIncFile);
+ QWidget::setTabOrder(leLATEXStyleIncFile, pbLATEXChooseStyleIncFile);
+ QWidget::setTabOrder(pbLATEXChooseStyleIncFile, cbTEXEmbedStyle);
+ QWidget::setTabOrder(cbTEXEmbedStyle, leTEXStyleFile);
+ QWidget::setTabOrder(leTEXStyleFile, leTEXStyleIncFile);
+ QWidget::setTabOrder(leTEXStyleIncFile, pbTEXChooseStyleIncFile);
+ QWidget::setTabOrder(pbTEXChooseStyleIncFile, cbRTFCharStyles);
+ QWidget::setTabOrder(cbRTFCharStyles, comboRTFPageSize);
+ QWidget::setTabOrder(comboRTFPageSize, leSVGWidth);
+ QWidget::setTabOrder(leSVGWidth, leSVGHeight);
+ QWidget::setTabOrder(leSVGHeight, cbSVGEmbedStyle);
+ QWidget::setTabOrder(cbSVGEmbedStyle, leSVGStyleFile);
+ QWidget::setTabOrder(leSVGStyleFile, leSVGStyleIncFile);
+ QWidget::setTabOrder(leSVGStyleIncFile, pbSVGChooseStyleIncFile);
+ QWidget::setTabOrder(pbSVGChooseStyleIncFile, comboTheme);
+ QWidget::setTabOrder(comboTheme, cbReformat);
+ QWidget::setTabOrder(cbReformat, comboReformat);
+ QWidget::setTabOrder(comboReformat, cbKwCase);
+ QWidget::setTabOrder(cbKwCase, comboKwCase);
+ QWidget::setTabOrder(comboKwCase, sbTabWidth);
+ QWidget::setTabOrder(sbTabWidth, cbWrapping);
+ QWidget::setTabOrder(cbWrapping, sbLineLength);
+ QWidget::setTabOrder(sbLineLength, cbAdvWrapping);
+ QWidget::setTabOrder(cbAdvWrapping, comboFontName);
+ QWidget::setTabOrder(comboFontName, leFontSize);
+ QWidget::setTabOrder(leFontSize, browserPreview);
+ QWidget::setTabOrder(browserPreview, pbStartConversion);
+ QWidget::setTabOrder(pbStartConversion, pbCopyFile2CP);
+
+ menuBar->addAction(menu_File->menuAction());
+ menuBar->addAction(menu_Help->menuAction());
+ menu_File->addAction(action_Open_files);
+ menu_File->addSeparator();
+ menu_File->addAction(action_Exit);
+ menu_Help->addAction(action_Tips);
+ menu_Help->addAction(action_Manual);
+ menu_Help->addAction(action_Changelog);
+ menu_Help->addAction(action_License);
+ menu_Help->addSeparator();
+ menu_Help->addAction(actionAbout_translations);
+ menu_Help->addSeparator();
+ menu_Help->addAction(action_About_Highlight);
+
+ retranslateUi(MainWindowClass);
+ QObject::connect(pbClearAll, SIGNAL(clicked()), lvInputFiles, SLOT(clear()));
+
+ tabIOSelection->setCurrentIndex(1);
+ tabWidget->setCurrentIndex(2);
+ stackedSpecificOptions->setCurrentIndex(0);
+ tabWidget1->setCurrentIndex(0);
+ comboRTFPageSize->setCurrentIndex(1);
+
+
+ QMetaObject::connectSlotsByName(MainWindowClass);
+ } // setupUi
+
+ void retranslateUi(QMainWindow *MainWindowClass)
+ {
+ MainWindowClass->setWindowTitle(QApplication::translate("MainWindowClass", "Highlight", 0, QApplication::UnicodeUTF8));
+ action_Open_files->setText(QApplication::translate("MainWindowClass", "&Open files", 0, QApplication::UnicodeUTF8));
+ action_Exit->setText(QApplication::translate("MainWindowClass", "&Exit", 0, QApplication::UnicodeUTF8));
+ action_Load->setText(QApplication::translate("MainWindowClass", "&Load", 0, QApplication::UnicodeUTF8));
+ action_Save->setText(QApplication::translate("MainWindowClass", "&Save", 0, QApplication::UnicodeUTF8));
+ actionLoad_default_project->setText(QApplication::translate("MainWindowClass", "Load &default project", 0, QApplication::UnicodeUTF8));
+ action_Manual->setText(QApplication::translate("MainWindowClass", "Readme", 0, QApplication::UnicodeUTF8));
+ action_Tips->setText(QApplication::translate("MainWindowClass", "&Tips", 0, QApplication::UnicodeUTF8));
+ action_Changelog->setText(QApplication::translate("MainWindowClass", "&Changelog", 0, QApplication::UnicodeUTF8));
+ action_License->setText(QApplication::translate("MainWindowClass", "&License", 0, QApplication::UnicodeUTF8));
+ action_About_Highlight->setText(QApplication::translate("MainWindowClass", "&About Highlight", 0, QApplication::UnicodeUTF8));
+ actionAbout_translations->setText(QApplication::translate("MainWindowClass", "About &translations", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ pbOpenFiles->setToolTip(QApplication::translate("MainWindowClass", "Choose the source code files you want to convert.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_WHATSTHIS
+ pbOpenFiles->setWhatsThis(QString());
+#endif // QT_NO_WHATSTHIS
+ pbOpenFiles->setText(QApplication::translate("MainWindowClass", "Choose input files", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ lvInputFiles->setToolTip(QApplication::translate("MainWindowClass", "List of input files.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ pbClearSelection->setToolTip(QApplication::translate("MainWindowClass", "Remove the selected input files.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbClearSelection->setText(QApplication::translate("MainWindowClass", "Clear selection", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ pbClearAll->setToolTip(QApplication::translate("MainWindowClass", "Remove all input files.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbClearAll->setText(QApplication::translate("MainWindowClass", "Clear all", 0, QApplication::UnicodeUTF8));
+ label_11->setText(QApplication::translate("MainWindowClass", "Output destination:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leOutputDest->setToolTip(QApplication::translate("MainWindowClass", "Output directory", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ pbOutputDest->setToolTip(QApplication::translate("MainWindowClass", "Select the output directory.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbOutputDest->setText(QApplication::translate("MainWindowClass", "...", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbWrite2Src->setToolTip(QApplication::translate("MainWindowClass", "Save output in the input file directories.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbWrite2Src->setText(QApplication::translate("MainWindowClass", "Write to source directories", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ pbStartConversion->setToolTip(QApplication::translate("MainWindowClass", "Start the conversion of your input files.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbStartConversion->setText(QApplication::translate("MainWindowClass", "Convert files", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ pbCopyFile2CP->setToolTip(QApplication::translate("MainWindowClass", "Copy highlighted code of the seleted file into the clipboard.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbCopyFile2CP->setText(QApplication::translate("MainWindowClass", "Copy file to clipboard", 0, QApplication::UnicodeUTF8));
+ tabIOSelection->setTabText(tabIOSelection->indexOf(tab_file_io), QApplication::translate("MainWindowClass", "Files", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ pbPasteFromCB->setToolTip(QApplication::translate("MainWindowClass", "Paste clipboard content into the preview window.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbPasteFromCB->setText(QApplication::translate("MainWindowClass", "Paste from clipboard", 0, QApplication::UnicodeUTF8));
+ label_13->setText(QApplication::translate("MainWindowClass", "Select syntax:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ comboSelectSyntax->setToolTip(QApplication::translate("MainWindowClass", "Select the correct syntax of the code snippet.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ pbCopyToCP->setToolTip(QApplication::translate("MainWindowClass", "Copy highlighted code into the clipboard.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbCopyToCP->setText(QApplication::translate("MainWindowClass", "Copy preview to clipboard", 0, QApplication::UnicodeUTF8));
+ tabIOSelection->setTabText(tabIOSelection->indexOf(tab_clipboard), QApplication::translate("MainWindowClass", "Clipboard", 0, QApplication::UnicodeUTF8));
+ label_2->setText(QApplication::translate("MainWindowClass", "Output format:", 0, QApplication::UnicodeUTF8));
+ comboFormat->clear();
+ comboFormat->insertItems(0, QStringList()
+ << QApplication::translate("MainWindowClass", "HTML", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "XHTML", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "LaTeX", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "TeX", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "RTF", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "SVG", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "XML", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "BBCode", 0, QApplication::UnicodeUTF8)
+ );
+#ifndef QT_NO_TOOLTIP
+ comboFormat->setToolTip(QApplication::translate("MainWindowClass", "Choose an output format.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ cbIncLineNo->setToolTip(QApplication::translate("MainWindowClass", "Add line numbers to the output.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbIncLineNo->setText(QApplication::translate("MainWindowClass", "Add line numbers", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ sbLineNoWidth->setToolTip(QApplication::translate("MainWindowClass", "Select the line number width.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ cbPadZeroes->setToolTip(QApplication::translate("MainWindowClass", "Fill leading space of line numbers with zeroes.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbPadZeroes->setText(QApplication::translate("MainWindowClass", "Pad with zeroes", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbFragment->setToolTip(QApplication::translate("MainWindowClass", "Generate output without document header and footer.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbFragment->setText(QApplication::translate("MainWindowClass", "Omit header and footer", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbValidateInput->setToolTip(QApplication::translate("MainWindowClass", "Test if input data is not binary.\n"
+"Removes Unicode BOM mark.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbValidateInput->setText(QApplication::translate("MainWindowClass", "Validate input data", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbEncoding->setToolTip(QApplication::translate("MainWindowClass", "Set the output file ancoding.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbEncoding->setText(QApplication::translate("MainWindowClass", "Set encoding:", 0, QApplication::UnicodeUTF8));
+ comboEncoding->clear();
+ comboEncoding->insertItems(0, QStringList()
+ << QApplication::translate("MainWindowClass", "ISO-8859-1", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-2", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-3", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-4", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-5", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-6", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-7", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-8", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-9", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-10", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-11", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-12", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-13", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-14", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "ISO-8859-15", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "UTF-8", 0, QApplication::UnicodeUTF8)
+ );
+#ifndef QT_NO_TOOLTIP
+ comboEncoding->setToolTip(QApplication::translate("MainWindowClass", "Select or define the encoding.\n"
+"The result has to match the input file encoding.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ tabWidget->setTabText(tabWidget->indexOf(page_general), QApplication::translate("MainWindowClass", "General", 0, QApplication::UnicodeUTF8));
+ label_17->setText(QApplication::translate("MainWindowClass", "HTML options", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbHTMLEmbedStyle->setToolTip(QApplication::translate("MainWindowClass", "Include the style information in each output file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbHTMLEmbedStyle->setText(QApplication::translate("MainWindowClass", "Embed style (CSS)", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbHTMLInlineCSS->setToolTip(QApplication::translate("MainWindowClass", "Add CSS information to each tag (do not use CSS class definitions).", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbHTMLInlineCSS->setText(QApplication::translate("MainWindowClass", "Inline CSS", 0, QApplication::UnicodeUTF8));
+ label_19->setText(QApplication::translate("MainWindowClass", "Stylesheet file:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leHTMLStyleFile->setToolTip(QApplication::translate("MainWindowClass", "Name of the referenced style file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ leHTMLStyleFile->setText(QApplication::translate("MainWindowClass", "highlight.css", 0, QApplication::UnicodeUTF8));
+ label_20->setText(QApplication::translate("MainWindowClass", "Include:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leHTMLStyleIncFile->setToolTip(QApplication::translate("MainWindowClass", "Path of the CSS include file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ pbHTMLChooseStyleIncFile->setToolTip(QApplication::translate("MainWindowClass", "Select a CSS include file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbHTMLChooseStyleIncFile->setText(QApplication::translate("MainWindowClass", "...", 0, QApplication::UnicodeUTF8));
+ label->setText(QApplication::translate("MainWindowClass", "CSS class prefix:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leHTMLCssPrefix->setToolTip(QApplication::translate("MainWindowClass", "Add a CSS class name prefix to avoid namespace clashes.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ leHTMLCssPrefix->setText(QString());
+ tabWidget1->setTabText(tabWidget1->indexOf(tabWidgetPage1), QApplication::translate("MainWindowClass", "Stylesheets", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbHTMLIndex->setToolTip(QApplication::translate("MainWindowClass", "Generate an index file with hyperlinks to all outputted files.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbHTMLIndex->setText(QApplication::translate("MainWindowClass", "Generate index file", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbHTMLCtags->setToolTip(QApplication::translate("MainWindowClass", "Read a ctags file and add the included metainformation as tooltips.\n"
+"See ctags.sf.net for details.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbHTMLCtags->setText(QApplication::translate("MainWindowClass", "Read ctags file:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leHTMLCtagsFile->setToolTip(QApplication::translate("MainWindowClass", "Path of the ctags file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ pbHTMLChooseTagsFile->setToolTip(QApplication::translate("MainWindowClass", "Choose a ctags file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbHTMLChooseTagsFile->setText(QApplication::translate("MainWindowClass", "...", 0, QApplication::UnicodeUTF8));
+ tabWidget1->setTabText(tabWidget1->indexOf(tabWidgetPage2), QApplication::translate("MainWindowClass", "Index/ctags", 0, QApplication::UnicodeUTF8));
+ label_8->setText(QApplication::translate("MainWindowClass", "Line numbering options:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbHTMLAnchors->setToolTip(QApplication::translate("MainWindowClass", "Add an achor to each line.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbHTMLAnchors->setText(QApplication::translate("MainWindowClass", "Add line anchors", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbHTMLFileNameAnchor->setToolTip(QApplication::translate("MainWindowClass", "Add the filename as prefix to the anchors.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbHTMLFileNameAnchor->setText(QApplication::translate("MainWindowClass", "Include file name in anchor", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbHTMLOrderedList->setToolTip(QApplication::translate("MainWindowClass", "Output the lines within an ordered list.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbHTMLOrderedList->setText(QApplication::translate("MainWindowClass", "Output as ordered list", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbHTMLEnclosePreTags->setToolTip(QApplication::translate("MainWindowClass", "Add &lt;pre&gt; tags to the output, if the flag \"No document header and footer\" is selected.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbHTMLEnclosePreTags->setText(QApplication::translate("MainWindowClass", "Enclose in pre tags", 0, QApplication::UnicodeUTF8));
+ tabWidget1->setTabText(tabWidget1->indexOf(tabWidgetPage3), QApplication::translate("MainWindowClass", "Misc", 0, QApplication::UnicodeUTF8));
+ label_18->setText(QApplication::translate("MainWindowClass", "LaTeX options", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbLATEXEscQuotes->setToolTip(QApplication::translate("MainWindowClass", "Replace quotes by dq sequences.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbLATEXEscQuotes->setText(QApplication::translate("MainWindowClass", "Escape quotes", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbLATEXBabel->setToolTip(QApplication::translate("MainWindowClass", "Make output Babel compatible.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbLATEXBabel->setText(QApplication::translate("MainWindowClass", "Add Babel compatibility", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbLATEXPrettySymbols->setToolTip(QApplication::translate("MainWindowClass", "Replace default symbols (brackets, tilde) by nice redefinitions.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbLATEXPrettySymbols->setText(QApplication::translate("MainWindowClass", "Add pretty symbols", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbLATEXEmbedStyle->setToolTip(QApplication::translate("MainWindowClass", "Include the style information in each output file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbLATEXEmbedStyle->setText(QApplication::translate("MainWindowClass", "Embed style (defs)", 0, QApplication::UnicodeUTF8));
+ label_21->setText(QApplication::translate("MainWindowClass", "Stylesheet file:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leLATEXStyleFile->setToolTip(QApplication::translate("MainWindowClass", "Name of the referenced style file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ leLATEXStyleFile->setText(QApplication::translate("MainWindowClass", "highlight.sty", 0, QApplication::UnicodeUTF8));
+ label_22->setText(QApplication::translate("MainWindowClass", "Stylesheet include file:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leLATEXStyleIncFile->setToolTip(QApplication::translate("MainWindowClass", "Path of the style include file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ pbLATEXChooseStyleIncFile->setToolTip(QApplication::translate("MainWindowClass", "Select a style include file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbLATEXChooseStyleIncFile->setText(QApplication::translate("MainWindowClass", "...", 0, QApplication::UnicodeUTF8));
+ label_26->setText(QApplication::translate("MainWindowClass", "TeX options", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbTEXEmbedStyle->setToolTip(QApplication::translate("MainWindowClass", "Include the style information in each output file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbTEXEmbedStyle->setText(QApplication::translate("MainWindowClass", "Embed style (macros)", 0, QApplication::UnicodeUTF8));
+ label_24->setText(QApplication::translate("MainWindowClass", "Stylesheet file:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leTEXStyleFile->setToolTip(QApplication::translate("MainWindowClass", "Name of the referenced style file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ leTEXStyleFile->setText(QApplication::translate("MainWindowClass", "highlight.sty", 0, QApplication::UnicodeUTF8));
+ label_25->setText(QApplication::translate("MainWindowClass", "Stylesheet include file:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leTEXStyleIncFile->setToolTip(QApplication::translate("MainWindowClass", "Path of the style include file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ pbTEXChooseStyleIncFile->setToolTip(QApplication::translate("MainWindowClass", "Select a style include file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbTEXChooseStyleIncFile->setText(QApplication::translate("MainWindowClass", "...", 0, QApplication::UnicodeUTF8));
+ label_15->setText(QApplication::translate("MainWindowClass", "RTF options", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ cbRTFCharStyles->setToolTip(QApplication::translate("MainWindowClass", "Add character stylesheets with formatting information.\n"
+"You can select the stylesheets in your word processor to reformat additional text.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbRTFCharStyles->setText(QApplication::translate("MainWindowClass", "Add character styles", 0, QApplication::UnicodeUTF8));
+ label_9->setText(QApplication::translate("MainWindowClass", "Page size:", 0, QApplication::UnicodeUTF8));
+ comboRTFPageSize->clear();
+ comboRTFPageSize->insertItems(0, QStringList()
+ << QApplication::translate("MainWindowClass", "A3", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "A4", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "A5", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "B4", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "B5", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "B6", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "Letter", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "Legal", 0, QApplication::UnicodeUTF8)
+ );
+#ifndef QT_NO_TOOLTIP
+ comboRTFPageSize->setToolTip(QApplication::translate("MainWindowClass", "Select a page size.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ label_16->setText(QApplication::translate("MainWindowClass", "SVG options", 0, QApplication::UnicodeUTF8));
+ label_10->setText(QApplication::translate("MainWindowClass", "Image size:", 0, QApplication::UnicodeUTF8));
+ label_3->setText(QApplication::translate("MainWindowClass", "Width:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leSVGWidth->setToolTip(QApplication::translate("MainWindowClass", "Enter the SVG width (may contain units).", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ label_12->setText(QApplication::translate("MainWindowClass", "Height:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leSVGHeight->setToolTip(QApplication::translate("MainWindowClass", "Enter the SVG height (may contain units).", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ cbSVGEmbedStyle->setToolTip(QApplication::translate("MainWindowClass", "Include the style information in each output file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbSVGEmbedStyle->setText(QApplication::translate("MainWindowClass", "Embed style (CSS)", 0, QApplication::UnicodeUTF8));
+ label_29->setText(QApplication::translate("MainWindowClass", "Stylesheet file:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leSVGStyleFile->setToolTip(QApplication::translate("MainWindowClass", "Name of the referenced style file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ leSVGStyleFile->setText(QApplication::translate("MainWindowClass", "highlight.css", 0, QApplication::UnicodeUTF8));
+ label_30->setText(QApplication::translate("MainWindowClass", "Stylesheet include file:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leSVGStyleIncFile->setToolTip(QApplication::translate("MainWindowClass", "Path of the CSS include file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ pbSVGChooseStyleIncFile->setToolTip(QApplication::translate("MainWindowClass", "Select a style include file.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ pbSVGChooseStyleIncFile->setText(QApplication::translate("MainWindowClass", "...", 0, QApplication::UnicodeUTF8));
+ label_7->setText(QApplication::translate("MainWindowClass", "No options defined.", 0, QApplication::UnicodeUTF8));
+ tabWidget->setTabText(tabWidget->indexOf(page_output_spec), QApplication::translate("MainWindowClass", "Output specific", 0, QApplication::UnicodeUTF8));
+ label_5->setText(QApplication::translate("MainWindowClass", "Color theme:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ comboTheme->setToolTip(QApplication::translate("MainWindowClass", "Select a colour theme.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ cbReformat->setToolTip(QApplication::translate("MainWindowClass", "Reformat and indent your code.\n"
+"This feature is enabled tor C, C++, C# and Java code.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbReformat->setText(QApplication::translate("MainWindowClass", "Reformat:", 0, QApplication::UnicodeUTF8));
+ comboReformat->clear();
+ comboReformat->insertItems(0, QStringList()
+ << QApplication::translate("MainWindowClass", "Allman", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "Banner", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "GNU", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "Horstmann", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "Java", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "K&R", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "Linux", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "OTBS", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "Stroustrup", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "Whitesmith", 0, QApplication::UnicodeUTF8)
+ );
+#ifndef QT_NO_TOOLTIP
+ comboReformat->setToolTip(QApplication::translate("MainWindowClass", "Choose a formatting scheme.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ cbKwCase->setToolTip(QApplication::translate("MainWindowClass", "Change the keyword case.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbKwCase->setText(QApplication::translate("MainWindowClass", "Keyword case:", 0, QApplication::UnicodeUTF8));
+ comboKwCase->clear();
+ comboKwCase->insertItems(0, QStringList()
+ << QApplication::translate("MainWindowClass", "UPPER", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "lower", 0, QApplication::UnicodeUTF8)
+ << QApplication::translate("MainWindowClass", "Capitalize", 0, QApplication::UnicodeUTF8)
+ );
+#ifndef QT_NO_TOOLTIP
+ comboKwCase->setToolTip(QApplication::translate("MainWindowClass", "Select a keyword case.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ label_6->setText(QApplication::translate("MainWindowClass", "Tab width:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ sbTabWidth->setToolTip(QApplication::translate("MainWindowClass", "Enter the number of spaces which replace a tab.\n"
+"Set the width to 0 to keep tabs.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ cbWrapping->setToolTip(QApplication::translate("MainWindowClass", "Enable line wrapping.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbWrapping->setText(QApplication::translate("MainWindowClass", "Line wrapping", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ sbLineLength->setToolTip(QApplication::translate("MainWindowClass", "Enter the maximum line length.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_TOOLTIP
+ cbAdvWrapping->setToolTip(QApplication::translate("MainWindowClass", "Indent statements and function parameters after wrapping.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ cbAdvWrapping->setText(QApplication::translate("MainWindowClass", "Intelligent wrapping", 0, QApplication::UnicodeUTF8));
+ label_23->setText(QApplication::translate("MainWindowClass", "Font name:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ comboFontName->setToolTip(QApplication::translate("MainWindowClass", "Select or enter the font name.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ label_4->setText(QApplication::translate("MainWindowClass", "Font size:", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ leFontSize->setToolTip(QApplication::translate("MainWindowClass", "Enter the font size.", 0, QApplication::UnicodeUTF8));
+#endif // QT_NO_TOOLTIP
+ tabWidget->setTabText(tabWidget->indexOf(page_formatting), QApplication::translate("MainWindowClass", "Formatting", 0, QApplication::UnicodeUTF8));
+ lbPreview->setText(QApplication::translate("MainWindowClass", "Preview", 0, QApplication::UnicodeUTF8));
+#ifndef QT_NO_TOOLTIP
+ browserPreview->setToolTip(QString());
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_WHATSTHIS
+ browserPreview->setWhatsThis(QString());
+#endif // QT_NO_WHATSTHIS
+ label_14->setText(QApplication::translate("MainWindowClass", "Output progress:", 0, QApplication::UnicodeUTF8));
+ menu_File->setTitle(QApplication::translate("MainWindowClass", "&File", 0, QApplication::UnicodeUTF8));
+ menu_Help->setTitle(QApplication::translate("MainWindowClass", "&Help", 0, QApplication::UnicodeUTF8));
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class MainWindowClass: public Ui_MainWindowClass {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // UI_MAINWINDOW_H
diff --git a/support/highlight/src/gui-qt/ui_showtextfile.h b/support/highlight/src/gui-qt/ui_showtextfile.h
new file mode 100644
index 0000000000..d46b490858
--- /dev/null
+++ b/support/highlight/src/gui-qt/ui_showtextfile.h
@@ -0,0 +1,105 @@
+/********************************************************************************
+** Form generated from reading UI file 'showtextfile.ui'
+**
+** Created: Wed Mar 31 16:43:25 2010
+** by: Qt User Interface Compiler version 4.6.2
+**
+** WARNING! All changes made in this file will be lost when recompiling UI file!
+********************************************************************************/
+
+#ifndef UI_SHOWTEXTFILE_H
+#define UI_SHOWTEXTFILE_H
+
+#include <QtCore/QVariant>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QDialog>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QHeaderView>
+#include <QtGui/QLabel>
+#include <QtGui/QPushButton>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QTextEdit>
+#include <QtGui/QVBoxLayout>
+
+QT_BEGIN_NAMESPACE
+
+class Ui_ShowTextFile
+{
+public:
+ QVBoxLayout *verticalLayout;
+ QLabel *lbTitle;
+ QTextEdit *textEdit;
+ QHBoxLayout *horizontalLayout;
+ QSpacerItem *horizontalSpacer;
+ QPushButton *pushButton;
+
+ void setupUi(QDialog *ShowTextFile)
+ {
+ if (ShowTextFile->objectName().isEmpty())
+ ShowTextFile->setObjectName(QString::fromUtf8("ShowTextFile"));
+ ShowTextFile->setWindowModality(Qt::WindowModal);
+ ShowTextFile->resize(711, 442);
+ QIcon icon;
+ icon.addFile(QString::fromUtf8(":/hl_icon2.png"), QSize(), QIcon::Normal, QIcon::Off);
+ ShowTextFile->setWindowIcon(icon);
+ ShowTextFile->setModal(true);
+ verticalLayout = new QVBoxLayout(ShowTextFile);
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
+ lbTitle = new QLabel(ShowTextFile);
+ lbTitle->setObjectName(QString::fromUtf8("lbTitle"));
+ QFont font;
+ font.setPointSize(10);
+ font.setBold(true);
+ font.setWeight(75);
+ lbTitle->setFont(font);
+
+ verticalLayout->addWidget(lbTitle);
+
+ textEdit = new QTextEdit(ShowTextFile);
+ textEdit->setObjectName(QString::fromUtf8("textEdit"));
+ QFont font1;
+ font1.setFamily(QString::fromUtf8("Courier New"));
+ font1.setPointSize(8);
+ textEdit->setFont(font1);
+
+ verticalLayout->addWidget(textEdit);
+
+ horizontalLayout = new QHBoxLayout();
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
+ horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ horizontalLayout->addItem(horizontalSpacer);
+
+ pushButton = new QPushButton(ShowTextFile);
+ pushButton->setObjectName(QString::fromUtf8("pushButton"));
+ pushButton->setDefault(true);
+
+ horizontalLayout->addWidget(pushButton);
+
+
+ verticalLayout->addLayout(horizontalLayout);
+
+
+ retranslateUi(ShowTextFile);
+
+ QMetaObject::connectSlotsByName(ShowTextFile);
+ } // setupUi
+
+ void retranslateUi(QDialog *ShowTextFile)
+ {
+ ShowTextFile->setWindowTitle(QApplication::translate("ShowTextFile", "Show text", 0, QApplication::UnicodeUTF8));
+ lbTitle->setText(QApplication::translate("ShowTextFile", "TextLabel", 0, QApplication::UnicodeUTF8));
+ pushButton->setText(QApplication::translate("ShowTextFile", "OK", 0, QApplication::UnicodeUTF8));
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class ShowTextFile: public Ui_ShowTextFile {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // UI_SHOWTEXTFILE_H
diff --git a/support/highlight/src/makefile b/support/highlight/src/makefile
new file mode 100644
index 0000000000..e2dbabf684
--- /dev/null
+++ b/support/highlight/src/makefile
@@ -0,0 +1,218 @@
+# Simple Makefile for Highlight
+# This file will compile the highlight library and binaries.
+# See INSTALL for instructions.
+
+# Add -DHL_DATA_DIR=\"/your/path/\" to CFLAGS if you want to define a
+# custom installation directory not listed in INSTALL.
+# Copy *.conf, ./langDefs, ./themes amd ./indentSchemes to /your/path/.
+# See ../makefile for the definition of ${data_dir}
+
+# Add -DHL_CONFIG_DIR=\"/your/path/\" to define the configuration directory
+# (default: /etc/highlight)
+
+# Add -DCONFIG_FILE_PATH=\"/your/path/.highlightrc\" if you want to define a
+# custom path to the highlight configuration file (default: $HOME/.highlightrc)
+
+# See src/gui-qt/highlight.pro for the Qt GUI compilation options
+
+CXX=c++
+
+QMAKE=qmake
+
+CFLAGS:=-O2 ${CFLAGS}
+#CFLAGS:=-ggdb ${CFLAGS}
+
+SO_VERSION=2.13
+
+# Source paths
+CORE_DIR=./core/
+CLI_DIR=./cli/
+GUI_QT_DIR=./gui-qt/
+
+# Third-Party software paths
+ASTYLE_DIR=${CORE_DIR}astyle/
+REGEX_DIR=${CORE_DIR}re/
+
+ifndef HL_CONFIG_DIR
+ HL_CONFIG_DIR = /etc/highlight/
+endif
+ifndef HL_DATA_DIR
+ HL_DATA_DIR = /usr/share/highlight/
+endif
+ifdef PIC
+ CFLAGS+=-fPIC
+endif
+
+# Do not strip by default (Mac OS X lazy pointer issues)
+# Add -static to avoid linking with shared libs (can cause trouble when highlight
+# is run as service)
+#LDFLAGS =
+#LDFLAGS = ${LDFLAGS} -s
+#LDFLAGS= -Wl,--as-needed
+
+CXX_COMPILE=${CXX} ${CFLAGS} -c -I ${CORE_DIR}
+
+# Data directories (data dir, configuration file dir)
+CXX_DIR=-DHL_DATA_DIR=\"${HL_DATA_DIR}\" -DHL_CONFIG_DIR=\"${HL_CONFIG_DIR}\"
+
+AR=ar
+ARFLAGS=-crs
+
+# objects files to build the library
+CORE_OBJECTS:=configurationreader.o stylecolour.o stringtools.o \
+ xhtmlgenerator.o latexgenerator.o texgenerator.o rtfgenerator.o \
+ htmlgenerator.o ansigenerator.o xmlgenerator.o svggenerator.o codegenerator.o \
+ xterm256generator.o bbcodegenerator.o \
+ languagedefinition.o elementstyle.o documentstyle.o \
+ datadir.o preformatter.o platform_fs.o ctagsreader.o\
+ ASStreamIterator.o ASResource.o ASFormatter.o ASBeautifier.o ASEnhancer.o\
+ Pattern.o Matcher.o
+
+# command line interface
+CLI_OBJECTS:=arg_parser.o cmdlineoptions.o main.o help.o
+
+# Qt user interface
+GUI_OBJECTS:=${GUI_QT_DIR}main.cpp ${GUI_QT_DIR}mainwindow.cpp ${GUI_QT_DIR}io_report.cpp ${GUI_QT_DIR}showtextfile.cpp
+
+
+cli: libhighlight.a ${CLI_OBJECTS}
+ ${CXX} ${LDFLAGS} -o highlight ${CLI_OBJECTS} -L. -lhighlight
+
+lib-static libhighlight.a: ${CORE_OBJECTS}
+ ${AR} ${ARFLAGS} libhighlight.a ${CORE_OBJECTS}
+
+lib-shared libhighlight.so.1.0: ${CORE_OBJECTS}
+ ld -shared -soname libhighlight.so.1 -o libhighlight.so.${SO_VERSION} -lc ${CORE_OBJECTS}
+
+gui-qt: highlight-gui
+
+highlight-gui: libhighlight.a ${GUI_OBJECTS}
+ cd gui-qt && \
+ ${QMAKE} 'DEFINES+=DATA_DIR=\\\"${HL_DATA_DIR}\\\" CONFIG_DIR=\\\"${HL_CONFIG_DIR}\\\" DOC_DIR=\\\"${HL_DOC_DIR}\\\"' && \
+ make
+
+$(OBJECTFILES) : makefile
+
+ansigenerator.o: ${CORE_DIR}ansigenerator.cpp ${CORE_DIR}ansigenerator.h ${CORE_DIR}codegenerator.h
+ ${CXX_COMPILE} ${CORE_DIR}ansigenerator.cpp
+
+ASBeautifier.o: ${ASTYLE_DIR}ASBeautifier.cpp ${ASTYLE_DIR}astyle.h
+ ${CXX_COMPILE} ${ASTYLE_DIR}ASBeautifier.cpp
+
+ASFormatter.o: ${ASTYLE_DIR}ASFormatter.cpp ${ASTYLE_DIR}astyle.h
+ ${CXX_COMPILE} ${ASTYLE_DIR}ASFormatter.cpp
+
+ASResource.o: ${ASTYLE_DIR}ASResource.cpp ${ASTYLE_DIR}astyle.h
+ ${CXX_COMPILE} ${ASTYLE_DIR}ASResource.cpp
+
+ASEnhancer.o: ${ASTYLE_DIR}ASResource.cpp ${ASTYLE_DIR}astyle.h
+ ${CXX_COMPILE} ${ASTYLE_DIR}ASEnhancer.cpp
+
+ASStreamIterator.o: ${ASTYLE_DIR}ASStreamIterator.cpp ${ASTYLE_DIR}astyle.h
+ ${CXX_COMPILE} ${ASTYLE_DIR}ASStreamIterator.cpp
+
+cmdlineoptions.o: ${CLI_DIR}cmdlineoptions.cpp ${CLI_DIR}cmdlineoptions.h
+ ${CXX_COMPILE} ${CLI_DIR}cmdlineoptions.cpp
+
+codegenerator.o: ${CORE_DIR}codegenerator.cpp ${CORE_DIR}codegenerator.h ${CORE_DIR}languagedefinition.h \
+ ${CORE_DIR}configurationreader.h ${CORE_DIR}stringtools.h ${CORE_DIR}enums.h ${CORE_DIR}documentstyle.h \
+ ${CORE_DIR}elementstyle.h ${CORE_DIR}stylecolour.h ${ASTYLE_DIR}astyle.h ${CORE_DIR}preformatter.h \
+ ${CORE_DIR}htmlgenerator.h ${CORE_DIR}version.h ${CORE_DIR}charcodes.h ${CORE_DIR}xhtmlgenerator.h ${CORE_DIR}rtfgenerator.h \
+ ${CORE_DIR}latexgenerator.h ${CORE_DIR}texgenerator.h ${CORE_DIR}ansigenerator.h
+ ${CXX_COMPILE} ${CORE_DIR}codegenerator.cpp
+
+configurationreader.o: ${CORE_DIR}configurationreader.cpp ${CORE_DIR}configurationreader.h \
+ ${CORE_DIR}stringtools.h
+ ${CXX_COMPILE} ${CORE_DIR}configurationreader.cpp
+
+datadir.o: ${CORE_DIR}datadir.cpp ${CORE_DIR}datadir.h ${CORE_DIR}platform_fs.h
+ ${CXX_COMPILE} ${CORE_DIR}datadir.cpp ${CXX_DIR}
+
+platform_fs.o: ${CORE_DIR}platform_fs.cpp ${CORE_DIR}platform_fs.h
+ ${CXX_COMPILE} ${CORE_DIR}platform_fs.cpp
+
+documentstyle.o: ${CORE_DIR}documentstyle.cpp ${CORE_DIR}documentstyle.h ${CORE_DIR}configurationreader.h \
+ ${CORE_DIR}stringtools.h ${CORE_DIR}elementstyle.h ${CORE_DIR}stylecolour.h
+ ${CXX_COMPILE} ${CORE_DIR}documentstyle.cpp
+
+elementstyle.o: ${CORE_DIR}elementstyle.cpp ${CORE_DIR}elementstyle.h ${CORE_DIR}stylecolour.h
+ ${CXX_COMPILE} ${CORE_DIR}elementstyle.cpp
+
+help.o: ${CLI_DIR}help.cpp ${CLI_DIR}help.h
+ ${CXX_COMPILE} ${CLI_DIR}help.cpp
+
+htmlgenerator.o: ${CORE_DIR}htmlgenerator.cpp ${CORE_DIR}htmlgenerator.h ${CORE_DIR}codegenerator.h
+ ${CXX_COMPILE} ${CORE_DIR}htmlgenerator.cpp
+
+languagedefinition.o: ${CORE_DIR}languagedefinition.cpp ${CORE_DIR}languagedefinition.h \
+ ${CORE_DIR}configurationreader.h ${CORE_DIR}platform_fs.h ${CORE_DIR}enums.h ${CORE_DIR}stringtools.h
+ ${CXX_COMPILE} ${CORE_DIR}languagedefinition.cpp
+
+latexgenerator.o: ${CORE_DIR}latexgenerator.cpp ${CORE_DIR}latexgenerator.h ${CORE_DIR}codegenerator.h
+ ${CXX_COMPILE} ${CORE_DIR}latexgenerator.cpp
+
+bbcodegenerator.o: ${CORE_DIR}bbcodegenerator.cpp ${CORE_DIR}bbcodegenerator.h ${CORE_DIR}codegenerator.h
+ ${CXX_COMPILE} ${CORE_DIR}bbcodegenerator.cpp
+
+preformatter.o: ${CORE_DIR}preformatter.cpp ${CORE_DIR}preformatter.h ${CORE_DIR}stringtools.h
+ ${CXX_COMPILE} ${CORE_DIR}preformatter.cpp
+
+main.o: ${CLI_DIR}main.cpp ${CLI_DIR}main.h ${CLI_DIR}cmdlineoptions.h ${CORE_DIR}platform_fs.h \
+ ${CORE_DIR}configurationreader.h ${CORE_DIR}datadir.h ${CORE_DIR}enums.h ${CORE_DIR}codegenerator.h \
+ ${CORE_DIR}languagedefinition.h ${CORE_DIR}documentstyle.h ${CORE_DIR}elementstyle.h \
+ ${CORE_DIR}stylecolour.h ${ASTYLE_DIR}astyle.h ${CORE_DIR}preformatter.h \
+ ${CLI_DIR}help.h ${CORE_DIR}version.h
+ ${CXX_COMPILE} ${CLI_DIR}main.cpp ${CXX_DIR}
+
+rtfgenerator.o: ${CORE_DIR}rtfgenerator.cpp ${CORE_DIR}rtfgenerator.h ${CORE_DIR}codegenerator.h
+ ${CXX_COMPILE} ${CORE_DIR}rtfgenerator.cpp
+
+stringtools.o: ${CORE_DIR}stringtools.cpp ${CORE_DIR}stringtools.h
+ ${CXX_COMPILE} ${CORE_DIR}stringtools.cpp
+
+stylecolour.o: ${CORE_DIR}stylecolour.cpp ${CORE_DIR}stylecolour.h ${CORE_DIR}enums.h ${CORE_DIR}stringtools.h
+ ${CXX_COMPILE} ${CORE_DIR}stylecolour.cpp
+
+texgenerator.o: ${CORE_DIR}texgenerator.cpp ${CORE_DIR}texgenerator.h ${CORE_DIR}codegenerator.h
+ ${CXX_COMPILE} ${CORE_DIR}texgenerator.cpp
+
+xhtmlgenerator.o: ${CORE_DIR}xhtmlgenerator.cpp ${CORE_DIR}xhtmlgenerator.h ${CORE_DIR}htmlgenerator.h \
+ ${CORE_DIR}codegenerator.h
+ ${CXX_COMPILE} ${CORE_DIR}xhtmlgenerator.cpp
+
+xmlgenerator.o: ${CORE_DIR}xmlgenerator.cpp ${CORE_DIR}xmlgenerator.h ${CORE_DIR}codegenerator.h
+ ${CXX_COMPILE} ${CORE_DIR}xmlgenerator.cpp
+
+svggenerator.o: ${CORE_DIR}svggenerator.cpp ${CORE_DIR}svggenerator.h ${CORE_DIR}codegenerator.h
+ ${CXX_COMPILE} ${CORE_DIR}svggenerator.cpp
+
+xterm256generator.o: ${CORE_DIR}xterm256generator.cpp ${CORE_DIR}xterm256generator.h ${CORE_DIR}codegenerator.h
+ ${CXX_COMPILE} ${CORE_DIR}xterm256generator.cpp
+
+Matcher.o: ${REGEX_DIR}Matcher.cpp ${REGEX_DIR}Matcher.h
+ ${CXX_COMPILE} ${REGEX_DIR}Matcher.cpp
+
+Pattern.o: ${REGEX_DIR}Pattern.cpp ${REGEX_DIR}Pattern.h
+ ${CXX_COMPILE} ${REGEX_DIR}Pattern.cpp
+
+arg_parser.o: ${CLI_DIR}arg_parser.cc ${CLI_DIR}arg_parser.h
+ ${CXX_COMPILE} ${CLI_DIR}arg_parser.cc
+
+ctagsreader.o: ${CORE_DIR}ctagsreader.cpp ${CORE_DIR}ctagsreader.h
+ ${CXX_COMPILE} ${CORE_DIR}ctagsreader.cpp
+
+
+.PHONY: ${GUI_OBJECTS}
+
+clean:
+ @rm -f *.o
+ @rm -f ./highlight
+ @rm -f ./highlight-gui
+ @rm -f ./libhighlight.a
+ @rm -f ./libhighlight.so.*
+ @rm -f ./.deps/*
+ @rm -f gui-qt/*.o
+ @rm -f gui-qt/Makefile*
+ @rm -f gui-qt/object_script.*
+ @rm -f gui-qt/ui_*.h gui-qt/qrc_*.cpp gui-qt/moc_*.cpp
+ @rm -rf gui-qt/highlight-gui.gch/