Source-highlight Qt, a library for syntax highlighting for Qt, using GNU Source-highlight.
This is Edition 0.2.2 of the Source-highlight Qt Library manual.
This file documents Source-highlight Qt Library version 0.2.2.
This manual is for Source-highlight Qt Library (version 0.2.2, 6 March 2010), which given a source file, produces a document with syntax highlighting.
Copyright © 2009 Lorenzo Bettini, http://www.lorenzobettini.it.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover Texts being “A GNU Manual,” and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled “GNU Free Documentation License.”(a) The FSF's Back-Cover Text is: “You have freedom to copy and modify this GNU Manual, like GNU software. Copies published by the Free Software Foundation raise funds for GNU development.”
Source-highlight-qt is a library for performing syntax highlighting in Qt documents by relying on GNU Source-Highlight library, http://www.gnu.org/software/src-highlite/.
Although the use of GNU Source-highlight library is pretty hidden by this library, so the programmer must not need the details of GNU Source-highlight library, yet, some general notions of GNU Source-highlight might be useful (especially how language definition files are defined, where the configuration files are stored, etc.).
This library provides an implementation of the qt abstract class
QSyntaxHighlighter
class, and it deals both with Qt3 and Qt4,
although you will need to build a separate version of the library for
the two different qt frameworks (see See Installation).
Please note, the Qt3 version has less features and it is there only for
old qt applications; furthermore, QSyntaxHighlighter
class in Qt3
has some design problems which make it quite inefficient to use.
Thus, in this manual, we basically describe the Qt4 classes; the corresponding Qt3 classes (if any) have a similar name but with Qt3, and their usage is similar to the corresponding Qt4 ones.
Here we list some software related to Source-highlight-qt library in the sense that it uses it as a backend (i.e., provides an interface to source-highlight) or it uses some of its features (e.g., definition files):
You can build and install Source-highlight-qt library either using
the configure
script (suggested way) or using qmake
.
If you're used to compiling Linux software that comes with sources you may simply follow the usual procedure, i.e., untar the file you downloaded in a directory and then:
cd <source code main directory> ./configure make make install
Note: unless you specify a different install directory by
--prefix
option of
configure (e.g. ./configure --prefix=<your home>
),
you must be root to run make install
.
Source-highlight-qt library requires GNU Source-highlight library, which is part of
GNU Source-highlight, http://www.gnu.org/software/src-highlite/, thus you need to install that
first. If you install GNU Source-highlight in a system path, e.g.,
/usr
, then the configure
should be able to find it,
by relying on
pkg-config
1
configuration file (metadata file), source-highlight.pc. On the
contrary, you must specify the path where the
source-highlight.pc is installed using the environment variable
PKG_CONFIG_PATH
.
For instance, if you install GNU Source-highlight into
/usr/local/
, the .pc file will be installed into
/usr/local/lib/pkgconfig
, and then you'll need to
set PKG_CONFIG_PATH
accordingly, or simply call the
configure
script as follows:
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure
In case you have both Qt3 and Qt4 installed on your system,
and you want to make sure to build the Qt4 version of the library you
need use the configure
's command line option
--enable-qt4
(--enable-qt3
will force the Qt3 build).
Otherwise, the default version of Qt found in the system will be used.
IMPORTANT: you cannot build the Qt4 and Qt3 version in the same directory: you must use a different build directory for each version.
You may want to run ./configure --help
to see all the possible
options that can be passed to the configuration script.
Files will be installed in the following directories:
header files
prefix/include/srchiliteqt
library files
prefix/lib
documentation
prefix/share/doc/source-highlight-qt
library examples
prefix/share/doc/source-highlight-qt/examples
library API documentation
prefix/share/doc/source-highlight-qt/api
Default value for prefix is /usr/local
but you may change it with --prefix
option to configure. For further configure
options, you
can run configure --help
.
If you want to build and install the API documentation of
Source-highlight-qt library, you need to run configure
with the
option --with-doxygen
, but you need the program Doxygen,
http://www.doxygen.org, to build the documentation.
The documentation will be installed in the following directory:
Library API documentation
prefix/share/doc/source-highlight-qt/api
Since version 0.2.1, Source-highlight-qt library can be
built also using qmake
, the build tool from Qt libraries
(http://qt.nokia.com). This was made available to build
Source-highlight-qt library on Windows based systems without using a Unix
shell, and in particular to build Source-highlight-qt library
with Microsoft MSVC compiler. You should use this method only if you
don't have a Unix shell or if you really need to use the MSVC compiler
(e.g., if you want to build Source-highlight-qt library to be used in MSVC
based programs.
Building with qmake is only supported for the Qt4 version of the library.
Note that if you want to build Source-highlight-qt library this way, you should build also GNU Source-highlight library with qmake. In particular, you still need the boost regex library, and if you use MSVC, you can find installation packages for this library at http://www.boostpro.com.
This build mechanism is still experimental, and, when using MSVC, only
a static version of GNU Source-highlight library can be built (not a .dll),
thus the same holds also for Source-highlight-qt library.
You can also use this method if you have the MinGW compiler,
http://www.mingw.org, (e.g.,
the one that comes with Qt Windows distribution) and you don't have
Msys (http://www.mingw.org/wiki/MSYS). Otherwise, you should
still use the configure
based mechanims.
Using qmake
, only a few options can be specified during the building
(besides the ones you usually use with qmake), and these options can
be specified only using environment variables:
BOOST_REGEX
boost_regex
will be used to link the boost library
(i.e., -lboost_regex
); if your boost regex library has a different
name you must specify this name using this environment variable; e.g.,
if the library file is called libboost_regex-mt.lib
or
boost_regex-mt.dll
you must set this variable to
boost_regex-mt
.
PKG_CONFIG_PATH
pkg-config
where to find .pc
file of GNU Source-highlight library
(in case you rely on pkg-config, see also the next item).
NO_PKGCONFIG
pkg-config
will still be used by qmake to
find GNU Source-highlight library; if you want to avoid this, then you must
set this variable to 1.
SOURCE_HIGHLIGHT_LIB
INCPATH
LIBS
Please, take into consideration that specifying the boost library
include and library paths is completely up to you, using
INCPATH
and LIBS
, if they're not in the system
path directories.
Also remember to always use the option -recursive
when running
qmake.
If you then want to run make install
, you can use the
variable INSTALL_ROOT
to prefix the installation path, which,
otherwise, is the root directory.
Currently, only header files, lib files and a demo will be installed when building with qmake: documentation file, with this method, will neither be built nor installed.
You can use Source-highlight-qt library in your programs, by including its headers and linking to the file libsource-highlight-qt4.ext or libsource-highlight-qt3.ext2.
All the classes of the library are part of the namespace
srchiliteqt
, and all the header files are in the subdirectory
srchiliteqt
.
If you use qmake
to build your programs that use
Source-highlight-qt library, you need to set the variables for
library and header files accordingly in your project file, e.g.,
LIBS += -L/usr/local/lib -lsource-highlight-qt4 INCLUDEPATH = /usr/local/include
Otherwise you can use the pkg-config capabilities of qmake and add to your project file
CONFIG += link_pkgconfig PKGCONFIG += source-highlight-qt4
and this will take care of setting LIBS
and INCLUDEPATH
using the meta file source-highlight-qt4.pc
. I personally prefer
this solution, since all the correct flags for Source-highlight-qt library
and its required libraries will be used according to the path where it
was installed.
Similarly to what was said in See Installation, if Source-highlight-qt library
is installed in a non-standard location, you'll have to set the
PKG_CONFIG_PATH
environment variable, before calling qmake,
e.g.,
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig qmake
You can take a look at the qeditexample
example program, which
uses qmake and pkg-config (this program is distributed separately,
but it is available from http://srchiliteqt.sourceforge.net).
More details on pkg-config are illustrated in See Using Automake and Autotools.
Another way to use Source-highlight-qt library in your program is
to rely on autotools, i.e., Automake, Autoconf, etc. In
particular, the library is installed with a
pkg-config
3
configuration file (metadata file), source-highlight-qt4.pc.
pkg-config is a tool for helping compiling applications and libraries. It helps you insert the correct compiler options on the command line so an application can use Source-highlight-qt library simply by running
g++ -o test test.cpp `pkg-config --libs --cflags source-highlight-qt4`
rather than hard-coding values on where to find the library. Moreover, this will provide also with the correct compiler flags and libraries used by GNU Source-highlight library itself, e.g., Boost Regex library.
Note that pkg-config
searches for .pc files in its
standard directories. If you installed the library in a non standard
directory, you'll need to set the PKG_CONFIG_PATH
environment
variable accordingly.
For instance, if I install the library into
/usr/local/lib
, the .pc file will be installed into
/usr/local/lib/pkgconfig
, and then I'll need to call
pkg-config
as follows:
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig \ pkg-config --libs --cflags source-highlight-qt4
In your configure.ac you can use the autoconf macro provided
by pkg-config
; here is an example:
# Checks for libraries. PKG_CHECK_MODULES(SRCHILITEQT, [source-highlight-qt4 >= 0.1]) AC_SUBST(SRCHILITEQT_CFLAGS) AC_SUBST(SRCHILITEQT_LIBS)
Then, you can use the variables SRCHILITEQT_CFLAGS
and
SRCHILITEQT_LIBS
in your makefiles accordingly.
For instance,
... AM_CPPFLAGS = $(SRCHILITEQT_CFLAGS) ... LDADD = $(SRCHILITEQT_LIBS) ...
Here we present the main classes of the Source-highlight-qt library, together
with some example of use. For the documentation of all the classes (and
methods of the classes) we refer to the generated API documentation (see
See Installation). Furthermore, we refer to the
qeditexample
example, which uses basically all the functionalities
and classes of Source-highlight-qt library.
We will present the Qt4 versions of the classes, since they provide much more functionalities than the Qt3 versions (See Introduction).
All the classes of the library are part of the namespace
srchiliteqt
, and all the header files are in the subdirectory
srchiliteqt
. Note that the classes of GNU Source-highlight library can
throw exceptions if errors are encountered (e.g., an input file cannot
be opened, or a language definition file cannot be parsed); the
exception classes can be found in the API documentation of
GNU Source-highlight library, and all exception classes inherit from
std::exception
class (see also Exceptions).
The main class of the library is Qt4SyntaxHighlighter
class which
implements the Qt base class QSyntaxHighlighter
class by using
GNU Source-highlight library. Thus, you can use it as you would use
QSyntaxHighlighter
class (we refer to Qt documentation for further
details), thus, you initialize an object of
Qt4SyntaxHighlighter
class with an object of
QTextDocument
class (or QTextEdit
class). Before the
Qt4SyntaxHighlighter
class highlighter can highlight the contents
you need to initialize it by specifying the language definition file to
use. Here's an example that will highlight the text editor contents
using the Java language definition file:
QTextEdit *editor = new QTextEdit; srchiliteqt::Qt4SyntaxHighlighter *highlighter = new srchiliteqt::Qt4SyntaxHighlighter(editor->document()); highlighter->init("java.lang");
and that's all that is needed! GNU Source-highlight library will take care of highlighting the contents of the editor.
The next one is a slightly more involved example (you can find it in the source directory tests and it is installed in the examples directory), where we use the language definition file specified at the command line, or a simple language definition file simple.lang)4:
/* * qt4_highlighter_example_main.cpp * * Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2009 * Copyright: See COPYING file that comes with this distribution */ #include <srchiliteqt/Qt4SyntaxHighlighter.h> #include <srchilite/versions.h> #include <QApplication> #include <QMainWindow> #include <QTextEdit> #include <iostream> #ifndef BASEDIR #define BASEDIR "./" #endif int main(int argc, char **argv) { QApplication app(argc, argv); QTextEdit *editor = new QTextEdit; srchiliteqt::Qt4SyntaxHighlighter *highlighter = new srchiliteqt::Qt4SyntaxHighlighter(editor->document()); if (argc > 1) highlighter->init(argv[1]); else { std::cout << "using " << BASEDIR "simple.lang" << std::endl; highlighter->init(BASEDIR "simple.lang"); } QMainWindow win(0); win.setCentralWidget(editor); win.setWindowTitle(QString("GNU Syntax Highlighter (using ") + QString(srchilite::Versions::getCompleteVersion().c_str()) + QString(")")); win.resize(700, 512); win.show(); return app.exec(); }
The next example (qt4_highlighter_edit_main.cpp) opens the file
specified at the command line, and uses the
Qt4SyntaxHighlighter
class initFromFileName
method for
detecting the language definition file to use, by using the file name
(e.g., it uses cpp.lang for foo.cpp, changelog.lang for ChangeLog, etc.):
int main(int argc, char **argv) { QApplication app(argc, argv); if (argc <= 1) { std::cerr << "you must specify the file to edit" << std::endl; return 1; } QTextEdit *editor = new QTextEdit; srchiliteqt::Qt4SyntaxHighlighter *highlighter = new srchiliteqt::Qt4SyntaxHighlighter(editor->document()); QMainWindow win(0); win.setCentralWidget(editor); QFile file(argv[1]); if (!file.open(QFile::ReadOnly | QFile::Text)) { std::cerr << QString("Cannot read file %1:\n%2.") .arg(argv[1]) .arg( file.errorString()).toStdString() << std::endl; return 1; } if (!highlighter->initFromFileName(argv[1])) { std::cerr << "cannot find an highlighting scheme for " << argv[1] << std::endl; return 1; } QTextStream in(&file); QApplication::setOverrideCursor(Qt::WaitCursor); editor->setPlainText(in.readAll()); QApplication::restoreOverrideCursor(); win.setWindowTitle(QString("GNU Syntax Highlighter (using ") + QString( srchilite::Versions::getCompleteVersion().c_str()) + QString(")")); win.resize(700, 512); win.show(); return app.exec(); }
In case you use a text editor in read only mode (e.g., just to show file
contents), you may want to set also the highlighter in read only mode,
by using setReadOnly
method. This will speed up the highlighting
procedure (since the highlighter will not need to store for each line
specific highlighting information).
The library also provides some gui classes (only for Qt4) that ready to
be used. The main one is TextEditHighlighted
class which is a
QTextEdit
class already with a Qt4SyntaxHighlighter
class
object. In particular, this specialized text editor automatically
selects the language definition file for highlighting according to the
file name (and if you change the file name, e.g., changing the file
extension, it automatically changes the language for highlighting
accordingly).
Two combo boxes can be used to show the language definition files
available in GNU Source-highlight and the style files (e.g., the fonts and
colors for highlighting language elements): LanguageComboBox
class
and StyleComboBox
class, respectively. If you connect these two
widgets to a TextEditHighlighted
class (see the methods in the
API documentation), the highlighting automatically changes when you choose
an element from these combo boxes. Here's an example:
// create a combo box for language definition file selections languageComboBox = new srchiliteqt::LanguageComboBox(); languageToolBar = addToolBar(tr("Language")); languageToolBar->addWidget(languageComboBox); // retrieve the current language by the text editor highlighter languageComboBox->setCurrentLanguage (textEdit->getHighlighter()->getLangFile()); // and connect it to our text editor textEdit->connectLanguageComboBox(languageComboBox); styleComboBox = new srchiliteqt::StyleComboBox; styleToolBar = addToolBar(tr("Style")); styleToolBar->addWidget(styleComboBox); styleComboBox->setCurrentStyle("default.style"); // each time we insert something it will be resized styleComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); textEdit->connectStyleComboBox(styleComboBox);
ColorDialog
class provides a dialog for modifying the
formatting colors and font styles (e.g., bold, italics, etc.) for
highlighting contents in the editor. The dialog automatically fills the
current properties by using the passed Qt4SyntaxHighlighter
class
object. You can use syncFormatters
method to update the formatters
of the highlighter with the value set in the dialog; here's an example:
ColorDialog dialog(textEdit->getHighlighter(), this); if (dialog.exec() == QDialog::Accepted) { dialog.syncFormatters(); textEdit->getHighlighter()->rehighlight(); // updating text editor colors is still up to you textEdit->changeColors (textEdit->getHighlighter()->getForegroundColor(), textEdit->getHighlighter()->getBackgroundColor()); }
Finally, SourceHighlightSettingsDialog
class provides a dialog for
modifying (and validating) source-highlight's specific settings (in this
version, only the data dir value of source-highlight, i.e., where
source-highlight looks for language definition files, style files,
etc.); here's an example:
srchiliteqt::SourceHighlightSettingsDialog dialog(this); dialog.setSourceHighlightDataDirPath(sourceHighlightDataDir); if (dialog.exec() == QDialog::Accepted) { if (sourceHighlightDataDir != dialog.getSourceHighlightDataDirPath()) { sourceHighlightDataDir = dialog.getSourceHighlightDataDirPath(); srchilite::Settings::setGlobalDataDir (sourceHighlightDataDir.toStdString()); reloadComboBoxes(); } } if (!srchilite::Settings::checkSettings()) { QMessageBox::critical(this, tr("qeditexample"), tr("Source-highlight settings are wrong!\n\ Please configure it correctly")); } else { // make sure to reload the source-highlight global instances srchilite::Instances::reload(); }
These gui classes are used in the program qeditexample
example,
which you can use as a starting point to see how to use these gui
classes in your program.
The classes of GNU Source-highlight library can throw exceptions if errors are
encountered (e.g., an input file cannot be opened, or a language
definition file cannot be parsed); the exception classes can be found in
the API documentation of GNU Source-highlight library, and all exception classes
inherit from std::exception
class. Each time the classes of
GNU Source-highlight library need to parse a language definition file, an output
format definition file, or a style file, an exception might be thrown,
and you should take care of catching them otherwise the GUI application
will simply terminate abruptly, with an error printed on the console.
For instance, TextEditHighlighted
class takes care of catching
these exceptions when using source-highlight classes that need to read a
language definition file or a style file:
void TextEditHighlighted::setHighlighter(const QString &langFile) { bool errorOnLangFile = false; // before removing this highlighter, make sure the language definition // file can be loaded. try { srchilite::Instances::getLangDefManager()->getHighlightState( langFile.toStdString()); } catch (const srchilite::ParserException &pe) { SourceHighlightExceptionBox::showMessageBox(pe, this); errorOnLangFile = true; } catch (const srchilite::IOException &ie) { SourceHighlightExceptionBox::showMessageBox(ie, this); errorOnLangFile = true; } catch (const std::exception &e) { SourceHighlightExceptionBox::showMessageBox(e, this); errorOnLangFile = true; } if (!errorOnLangFile) { // remove the previous highlighter (which also disconnects it from // the current editor, automatically) // otherwise there'll be more highlighters for the same doc! delete highlighter; // set Qt4SyntaxHighlighter for highlighting context highlighter = new srchiliteqt::Qt4SyntaxHighlighter(document()); highlighter->init(langFile, styleFile); changeColors(highlighter->getForegroundColor(), highlighter->getBackgroundColor()); } } void TextEditHighlighted::changeHighlightingStyle(const QString &newStyle) { // avoid to switch language if it's just the same if (newStyle.isEmpty() || newStyle == highlighter->getFormattingStyle()) return; try { // this will also rehighlight the contents highlighter->setFormattingStyle(newStyle); } catch (const srchilite::ParserException &pe) { SourceHighlightExceptionBox::showMessageBox(pe, this); } catch (const std::exception &e) { SourceHighlightExceptionBox::showMessageBox(e, this); } changeColors(highlighter->getForegroundColor(), highlighter->getBackgroundColor()); styleFile = newStyle; emit changedHighlightingStyle(newStyle); }
In particular, it shows a message box with the exception details by
using the utility SourceHighlightExceptionBox
class provided by
Source-highlight-qt library.
If you find a bug in Source-highlight-qt library, please use the bug report interface or the forums you find at http://srchiliteqt.sourceforge.net. Alternatively, you can send electronic mail to the main author (you find my email address at my home page, http://www.lorenzobettini.it).
--enable-qt3
: Building with the configure script--enable-qt4
: Building with the configure script--with-doxygen
: Building with the configure scriptColorDialog
class: Gui classesinitFromFileName
method: Main ClassesLanguageComboBox
class: Gui classesNO_PKGCONFIG
: Building with qmakePKG_CONFIG_PATH
: Using Automake and AutotoolsPKG_CONFIG_PATH
: Using qmakePKG_CONFIG_PATH
: Building with qmakePKG_CONFIG_PATH
: Building with the configure scriptqeditexample
example: Gui classesqeditexample
example: Main Classesqeditexample
example: Using qmakeQSyntaxHighlighter
class: Main ClassesQSyntaxHighlighter
class: IntroductionQt4SyntaxHighlighter
class: Gui classesQt4SyntaxHighlighter
class: Main ClassesQTextDocument
class: Main ClassesQTextEdit
class: Gui classesQTextEdit
class: Main ClassessetReadOnly
method: Main ClassesSOURCE_HIGHLIGHT_LIB
: Building with qmakeSourceHighlightExceptionBox
class: ExceptionsSourceHighlightSettingsDialog
class: Gui classesstd::exception
class: Exceptionsstd::exception
class: Main ClassesStyleComboBox
class: Gui classessyncFormatters
method: Gui classesTextEditHighlighted
class: ExceptionsTextEditHighlighted
class: Gui classes[1] http://pkg-config.freedesktop.org.
[2] The extension of course depends
on the library being shared or static, e.g., .so
, .la
,
.a
, and on the system
[3] http://pkg-config.freedesktop.org.
[4] you can ignore the BASEDIR
constant,
which is used by the makefile in case the tests are built in a different
directory from the source directory.