https://bfwiki.tellefsen.net//api.php?action=feedcontributions&user=OlivierSessink&feedformat=atomBluefish Wiki - User contributions [en]2024-03-28T18:09:41ZUser contributionsMediaWiki 1.38.2https://bfwiki.tellefsen.net//index.php?title=Compiling_Bluefish_from_source&diff=2909Compiling Bluefish from source2023-05-05T11:57:41Z<p>OlivierSessink: /* Fedora packages required */</p>
<hr />
<div>= Compiling bluefish from source tarballs =<br />
<br />
== installing the requirements ==<br />
<br />
Build requirements:<br />
* a C compiler (for example gcc or clang-gcc)<br />
* gnu make<br />
<br />
Library / header file requirements:<br />
* gtk+ 2 or 3 development files (sometimes called libgtk2.0-dev or libgtk2-devel, or libgtk-3-dev)<br />
* libxml2 development files (sometimes called libxml2-dev or libxml2-devel)<br />
<br />
Optional libraries / header files:<br />
* libenchant + development files (for spell checking, libenchant-dev)<br />
* libgucharmap + development files (for the character map side pane plugin, libgucharmap-dev)<br />
* python development files (python-dev or python-devel)<br />
<br />
=== Debian and Ubuntu packages required ===<br />
<pre><br />
apt install automake autoconf make libtool intltool libgtk-3-dev libxml2-dev libenchant-2-dev libgucharmap-2-90-dev python3-dev<br />
</pre><br />
==== Debian / Ubuntu packages for the upcoming 2.2.14 release ====<br />
<pre><br />
apt install automake autoconf make libtool autopoint libgtk-3-dev libxml2-dev libenchant-2-dev libgucharmap-2-90-dev python3-dev<br />
</pre><br />
=== Fedora packages required ===<br />
<pre><br />
dnf install automake autoconf libtool gtk3-devel enchant2-devel libxml2-devel gucharmap-devel python3-devel gettext-devel<br />
</pre><br />
<br />
== Getting and compiling ==<br />
* get the latest source from http://www.bennewitz.com/bluefish/stable/source/<br />
* unpack <br />
** for a gzipped file '''tar -xzf bluefish-2.2.xxxx.tar.gz'''<br />
** for a bzipped file '''tar -xjf bluefish-2.2.xxxx.tar.bz2'''<br />
* '''cd bluefish-2.2.xxxx'''<br />
* run '''./configure'''<br />
* run '''make'''<br />
* switch to root and run '''make install'''<br />
<br />
= Compiling bluefish straight from subversion =<br />
=== Building (assumes required packages have been installed) ===<br />
{{SVN|checkout}}<br />
cd bluefish-code/bluefish<br />
./autogen.sh<br />
./configure<br />
make<br />
sudo make install<br />
<br />
=== Debian and Ubuntu packages required to build from subversion ===<br />
<pre><br />
apt install libtool autopoint automake autoconf make libgtk-3-dev libenchant-2-dev libgucharmap-2-90-dev libxml2-dev subversion python3-dev<br />
</pre></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Compiling_Bluefish_from_source&diff=2908Compiling Bluefish from source2023-05-05T11:56:09Z<p>OlivierSessink: /* Fedora packages required */</p>
<hr />
<div>= Compiling bluefish from source tarballs =<br />
<br />
== installing the requirements ==<br />
<br />
Build requirements:<br />
* a C compiler (for example gcc or clang-gcc)<br />
* gnu make<br />
<br />
Library / header file requirements:<br />
* gtk+ 2 or 3 development files (sometimes called libgtk2.0-dev or libgtk2-devel, or libgtk-3-dev)<br />
* libxml2 development files (sometimes called libxml2-dev or libxml2-devel)<br />
<br />
Optional libraries / header files:<br />
* libenchant + development files (for spell checking, libenchant-dev)<br />
* libgucharmap + development files (for the character map side pane plugin, libgucharmap-dev)<br />
* python development files (python-dev or python-devel)<br />
<br />
=== Debian and Ubuntu packages required ===<br />
<pre><br />
apt install automake autoconf make libtool intltool libgtk-3-dev libxml2-dev libenchant-2-dev libgucharmap-2-90-dev python3-dev<br />
</pre><br />
==== Debian / Ubuntu packages for the upcoming 2.2.14 release ====<br />
<pre><br />
apt install automake autoconf make libtool autopoint libgtk-3-dev libxml2-dev libenchant-2-dev libgucharmap-2-90-dev python3-dev<br />
</pre><br />
=== Fedora packages required ===<br />
<pre><br />
dnf install automake autoconf gtk3-devel enchant2-devel libxml2-devel gucharmap-devel python3-devel gettext-devel<br />
</pre><br />
<br />
== Getting and compiling ==<br />
* get the latest source from http://www.bennewitz.com/bluefish/stable/source/<br />
* unpack <br />
** for a gzipped file '''tar -xzf bluefish-2.2.xxxx.tar.gz'''<br />
** for a bzipped file '''tar -xjf bluefish-2.2.xxxx.tar.bz2'''<br />
* '''cd bluefish-2.2.xxxx'''<br />
* run '''./configure'''<br />
* run '''make'''<br />
* switch to root and run '''make install'''<br />
<br />
= Compiling bluefish straight from subversion =<br />
=== Building (assumes required packages have been installed) ===<br />
{{SVN|checkout}}<br />
cd bluefish-code/bluefish<br />
./autogen.sh<br />
./configure<br />
make<br />
sudo make install<br />
<br />
=== Debian and Ubuntu packages required to build from subversion ===<br />
<pre><br />
apt install libtool autopoint automake autoconf make libgtk-3-dev libenchant-2-dev libgucharmap-2-90-dev libxml2-dev subversion python3-dev<br />
</pre></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Compiling_Bluefish_from_source&diff=2907Compiling Bluefish from source2023-05-05T11:55:55Z<p>OlivierSessink: /* installing the requirements */</p>
<hr />
<div>= Compiling bluefish from source tarballs =<br />
<br />
== installing the requirements ==<br />
<br />
Build requirements:<br />
* a C compiler (for example gcc or clang-gcc)<br />
* gnu make<br />
<br />
Library / header file requirements:<br />
* gtk+ 2 or 3 development files (sometimes called libgtk2.0-dev or libgtk2-devel, or libgtk-3-dev)<br />
* libxml2 development files (sometimes called libxml2-dev or libxml2-devel)<br />
<br />
Optional libraries / header files:<br />
* libenchant + development files (for spell checking, libenchant-dev)<br />
* libgucharmap + development files (for the character map side pane plugin, libgucharmap-dev)<br />
* python development files (python-dev or python-devel)<br />
<br />
=== Debian and Ubuntu packages required ===<br />
<pre><br />
apt install automake autoconf make libtool intltool libgtk-3-dev libxml2-dev libenchant-2-dev libgucharmap-2-90-dev python3-dev<br />
</pre><br />
==== Debian / Ubuntu packages for the upcoming 2.2.14 release ====<br />
<pre><br />
apt install automake autoconf make libtool autopoint libgtk-3-dev libxml2-dev libenchant-2-dev libgucharmap-2-90-dev python3-dev<br />
</pre><br />
=== Fedora packages required ===<br />
dnf install automake autoconf gtk3-devel enchant2-devel libxml2-devel gucharmap-devel python3-devel gettext-devel<br />
<br />
== Getting and compiling ==<br />
* get the latest source from http://www.bennewitz.com/bluefish/stable/source/<br />
* unpack <br />
** for a gzipped file '''tar -xzf bluefish-2.2.xxxx.tar.gz'''<br />
** for a bzipped file '''tar -xjf bluefish-2.2.xxxx.tar.bz2'''<br />
* '''cd bluefish-2.2.xxxx'''<br />
* run '''./configure'''<br />
* run '''make'''<br />
* switch to root and run '''make install'''<br />
<br />
= Compiling bluefish straight from subversion =<br />
=== Building (assumes required packages have been installed) ===<br />
{{SVN|checkout}}<br />
cd bluefish-code/bluefish<br />
./autogen.sh<br />
./configure<br />
make<br />
sudo make install<br />
<br />
=== Debian and Ubuntu packages required to build from subversion ===<br />
<pre><br />
apt install libtool autopoint automake autoconf make libgtk-3-dev libenchant-2-dev libgucharmap-2-90-dev libxml2-dev subversion python3-dev<br />
</pre></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Compiling_Bluefish_from_source&diff=2906Compiling Bluefish from source2023-05-05T11:50:04Z<p>OlivierSessink: /* Debian and Ubuntu packages required */</p>
<hr />
<div>= Compiling bluefish from source tarballs =<br />
<br />
== installing the requirements ==<br />
<br />
Build requirements:<br />
* a C compiler (for example gcc or clang-gcc)<br />
* gnu make<br />
<br />
Library / header file requirements:<br />
* gtk+ 2 or 3 development files (sometimes called libgtk2.0-dev or libgtk2-devel, or libgtk-3-dev)<br />
* libxml2 development files (sometimes called libxml2-dev or libxml2-devel)<br />
<br />
Optional libraries / header files:<br />
* libenchant + development files (for spell checking, libenchant-dev)<br />
* libgucharmap + development files (for the character map side pane plugin, libgucharmap-dev)<br />
* python development files (python-dev or python-devel)<br />
<br />
=== Debian and Ubuntu packages required ===<br />
<pre><br />
apt install automake autoconf make libtool intltool libgtk-3-dev libxml2-dev libenchant-2-dev libgucharmap-2-90-dev python3-dev<br />
</pre><br />
<br />
=== for the upcoming 2.2.14 release the following packages are required ===<br />
<pre><br />
apt install automake autoconf make libtool autopoint libgtk-3-dev libxml2-dev libenchant-2-dev libgucharmap-2-90-dev python3-dev<br />
</pre><br />
<br />
== Getting and compiling ==<br />
* get the latest source from http://www.bennewitz.com/bluefish/stable/source/<br />
* unpack <br />
** for a gzipped file '''tar -xzf bluefish-2.2.xxxx.tar.gz'''<br />
** for a bzipped file '''tar -xjf bluefish-2.2.xxxx.tar.bz2'''<br />
* '''cd bluefish-2.2.xxxx'''<br />
* run '''./configure'''<br />
* run '''make'''<br />
* switch to root and run '''make install'''<br />
<br />
= Compiling bluefish straight from subversion =<br />
=== Building (assumes required packages have been installed) ===<br />
{{SVN|checkout}}<br />
cd bluefish-code/bluefish<br />
./autogen.sh<br />
./configure<br />
make<br />
sudo make install<br />
<br />
=== Debian and Ubuntu packages required to build from subversion ===<br />
<pre><br />
apt install libtool autopoint automake autoconf make libgtk-3-dev libenchant-2-dev libgucharmap-2-90-dev libxml2-dev subversion python3-dev<br />
</pre></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Compiling_Bluefish_from_source&diff=2905Compiling Bluefish from source2023-05-05T11:49:21Z<p>OlivierSessink: /* Debian and Ubuntu packages required to build from subversion */</p>
<hr />
<div>= Compiling bluefish from source tarballs =<br />
<br />
== installing the requirements ==<br />
<br />
Build requirements:<br />
* a C compiler (for example gcc or clang-gcc)<br />
* gnu make<br />
<br />
Library / header file requirements:<br />
* gtk+ 2 or 3 development files (sometimes called libgtk2.0-dev or libgtk2-devel, or libgtk-3-dev)<br />
* libxml2 development files (sometimes called libxml2-dev or libxml2-devel)<br />
<br />
Optional libraries / header files:<br />
* libenchant + development files (for spell checking, libenchant-dev)<br />
* libgucharmap + development files (for the character map side pane plugin, libgucharmap-dev)<br />
* python development files (python-dev or python-devel)<br />
<br />
=== Debian and Ubuntu packages required ===<br />
* automake<br />
* autoconf<br />
* make<br />
* libtool<br />
* intltool<br />
* libgtk-3-dev<br />
* libxml2-dev<br />
and optional<br />
* libenchant-dev<br />
* libgucharmap-2-90-dev<br />
* python-dev<br />
=== for the upcoming 2.2.14 release the following packages are required ===<br />
<pre><br />
apt install automake autoconf make libtool autopoint libgtk-3-dev libxml2-dev libenchant-2-dev libgucharmap-2-90-dev python3-dev<br />
</pre><br />
<br />
== Getting and compiling ==<br />
* get the latest source from http://www.bennewitz.com/bluefish/stable/source/<br />
* unpack <br />
** for a gzipped file '''tar -xzf bluefish-2.2.xxxx.tar.gz'''<br />
** for a bzipped file '''tar -xjf bluefish-2.2.xxxx.tar.bz2'''<br />
* '''cd bluefish-2.2.xxxx'''<br />
* run '''./configure'''<br />
* run '''make'''<br />
* switch to root and run '''make install'''<br />
<br />
= Compiling bluefish straight from subversion =<br />
=== Building (assumes required packages have been installed) ===<br />
{{SVN|checkout}}<br />
cd bluefish-code/bluefish<br />
./autogen.sh<br />
./configure<br />
make<br />
sudo make install<br />
<br />
=== Debian and Ubuntu packages required to build from subversion ===<br />
<pre><br />
apt install libtool autopoint automake autoconf make libgtk-3-dev libenchant-2-dev libgucharmap-2-90-dev libxml2-dev subversion python3-dev<br />
</pre></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Compiling_Bluefish_from_source&diff=2904Compiling Bluefish from source2023-05-05T11:48:29Z<p>OlivierSessink: /* for the upcoming 2.2.14 release the following packages are required */</p>
<hr />
<div>= Compiling bluefish from source tarballs =<br />
<br />
== installing the requirements ==<br />
<br />
Build requirements:<br />
* a C compiler (for example gcc or clang-gcc)<br />
* gnu make<br />
<br />
Library / header file requirements:<br />
* gtk+ 2 or 3 development files (sometimes called libgtk2.0-dev or libgtk2-devel, or libgtk-3-dev)<br />
* libxml2 development files (sometimes called libxml2-dev or libxml2-devel)<br />
<br />
Optional libraries / header files:<br />
* libenchant + development files (for spell checking, libenchant-dev)<br />
* libgucharmap + development files (for the character map side pane plugin, libgucharmap-dev)<br />
* python development files (python-dev or python-devel)<br />
<br />
=== Debian and Ubuntu packages required ===<br />
* automake<br />
* autoconf<br />
* make<br />
* libtool<br />
* intltool<br />
* libgtk-3-dev<br />
* libxml2-dev<br />
and optional<br />
* libenchant-dev<br />
* libgucharmap-2-90-dev<br />
* python-dev<br />
=== for the upcoming 2.2.14 release the following packages are required ===<br />
<pre><br />
apt install automake autoconf make libtool autopoint libgtk-3-dev libxml2-dev libenchant-2-dev libgucharmap-2-90-dev python3-dev<br />
</pre><br />
<br />
== Getting and compiling ==<br />
* get the latest source from http://www.bennewitz.com/bluefish/stable/source/<br />
* unpack <br />
** for a gzipped file '''tar -xzf bluefish-2.2.xxxx.tar.gz'''<br />
** for a bzipped file '''tar -xjf bluefish-2.2.xxxx.tar.bz2'''<br />
* '''cd bluefish-2.2.xxxx'''<br />
* run '''./configure'''<br />
* run '''make'''<br />
* switch to root and run '''make install'''<br />
<br />
= Compiling bluefish straight from subversion =<br />
=== Building (assumes required packages have been installed) ===<br />
{{SVN|checkout}}<br />
cd bluefish-code/bluefish<br />
./autogen.sh<br />
./configure<br />
make<br />
sudo make install<br />
<br />
=== Debian and Ubuntu packages required to build from subversion ===<br />
* libtool<br />
* intltool<br />
* automake<br />
* autoconf<br />
* make<br />
* libgtk-3-dev<br />
* libenchant-dev<br />
* libgucharmap-2-90-dev<br />
* libxml2-dev<br />
* subversion<br />
* python-dev</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Compiling_Bluefish_from_source&diff=2903Compiling Bluefish from source2023-05-05T11:18:42Z<p>OlivierSessink: /* Debian and Ubuntu packages required */</p>
<hr />
<div>= Compiling bluefish from source tarballs =<br />
<br />
== installing the requirements ==<br />
<br />
Build requirements:<br />
* a C compiler (for example gcc or clang-gcc)<br />
* gnu make<br />
<br />
Library / header file requirements:<br />
* gtk+ 2 or 3 development files (sometimes called libgtk2.0-dev or libgtk2-devel, or libgtk-3-dev)<br />
* libxml2 development files (sometimes called libxml2-dev or libxml2-devel)<br />
<br />
Optional libraries / header files:<br />
* libenchant + development files (for spell checking, libenchant-dev)<br />
* libgucharmap + development files (for the character map side pane plugin, libgucharmap-dev)<br />
* python development files (python-dev or python-devel)<br />
<br />
=== Debian and Ubuntu packages required ===<br />
* automake<br />
* autoconf<br />
* make<br />
* libtool<br />
* intltool<br />
* libgtk-3-dev<br />
* libxml2-dev<br />
and optional<br />
* libenchant-dev<br />
* libgucharmap-2-90-dev<br />
* python-dev<br />
=== for the upcoming 2.2.14 release the following packages are required ===<br />
* automake<br />
* autoconf<br />
* make<br />
* libtool<br />
* autopoint<br />
* libgtk-3-dev<br />
* libxml2-dev<br />
* libenchant-2-dev<br />
* libgucharmap-2-90-dev<br />
* python3-dev<br />
<br />
== Getting and compiling ==<br />
* get the latest source from http://www.bennewitz.com/bluefish/stable/source/<br />
* unpack <br />
** for a gzipped file '''tar -xzf bluefish-2.2.xxxx.tar.gz'''<br />
** for a bzipped file '''tar -xjf bluefish-2.2.xxxx.tar.bz2'''<br />
* '''cd bluefish-2.2.xxxx'''<br />
* run '''./configure'''<br />
* run '''make'''<br />
* switch to root and run '''make install'''<br />
<br />
= Compiling bluefish straight from subversion =<br />
=== Building (assumes required packages have been installed) ===<br />
{{SVN|checkout}}<br />
cd bluefish-code/bluefish<br />
./autogen.sh<br />
./configure<br />
make<br />
sudo make install<br />
<br />
=== Debian and Ubuntu packages required to build from subversion ===<br />
* libtool<br />
* intltool<br />
* automake<br />
* autoconf<br />
* make<br />
* libgtk-3-dev<br />
* libenchant-dev<br />
* libgucharmap-2-90-dev<br />
* libxml2-dev<br />
* subversion<br />
* python-dev</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2900Writing language definition files2023-01-05T16:54:06Z<p>OlivierSessink: /* auto completion */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names that can be used in the language file:<br />
<br />
The '_foldable' suffix is hardcoded in bluefish. It should be followed by block_name that is used in the language file somewhere. The attribute block_name can be in an <element> tag. In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. <br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
The 'is_' suffix is hardcoded in bluefish. It should be followed by the language name. This is useful for include files that are included in several different languages. This option is not set by the user, it is always present during compilation.<br />
The following example starts a PHP open tag, but only if the file is being included in the PHP language:<br />
<group class="is_PHP"><element idref="e.php.short.open" /></group><br />
See more about this in the section '''Advanced group class/notclass values'''<br />
<br />
There are also a few global options that are hardcoded:<br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that for example attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
<br />
==== Limited regular expression support ====<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. You may use<br />
* a range of characters such as [a-z0-9;']<br />
* an inverted range such as [^0-9]<br />
* operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
* subpatterns such as ab(fg)?<br />
* the OR construction (foo|bar), but only within round braces<br />
<br />
Another limitation is that overlapping regular expressions result in undefined behavior. For example a construction like ([a-z]+p) will not work because p is part of the [a-z]+ so bluefish does not know when scanning a p if it is part of the [a-z]+ or it is the final p. <br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
<br />
<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. See also the section on hardcoded option names. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&gt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"><br />
<autocomplete append=" src=&amp;dquot;&amp;dquot; " /><br />
</tag><br />
</pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2899Writing language definition files2023-01-05T16:47:56Z<p>OlivierSessink: /* auto completion */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names that can be used in the language file:<br />
<br />
The '_foldable' suffix is hardcoded in bluefish. It should be followed by block_name that is used in the language file somewhere. The attribute block_name can be in an <element> tag. In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. <br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
The 'is_' suffix is hardcoded in bluefish. It should be followed by the language name. This is useful for include files that are included in several different languages. This option is not set by the user, it is always present during compilation.<br />
The following example starts a PHP open tag, but only if the file is being included in the PHP language:<br />
<group class="is_PHP"><element idref="e.php.short.open" /></group><br />
See more about this in the section '''Advanced group class/notclass values'''<br />
<br />
There are also a few global options that are hardcoded:<br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that for example attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
<br />
==== Limited regular expression support ====<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. You may use<br />
* a range of characters such as [a-z0-9;']<br />
* an inverted range such as [^0-9]<br />
* operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
* subpatterns such as ab(fg)?<br />
* the OR construction (foo|bar), but only within round braces<br />
<br />
Another limitation is that overlapping regular expressions result in undefined behavior. For example a construction like ([a-z]+p) will not work because p is part of the [a-z]+ so bluefish does not know when scanning a p if it is part of the [a-z]+ or it is the final p. <br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
<br />
<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. See also the section on hardcoded option names. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&gt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2898Writing language definition files2023-01-05T16:46:54Z<p>OlivierSessink: /* The tag tag in the definition section */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names that can be used in the language file:<br />
<br />
The '_foldable' suffix is hardcoded in bluefish. It should be followed by block_name that is used in the language file somewhere. The attribute block_name can be in an <element> tag. In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. <br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
The 'is_' suffix is hardcoded in bluefish. It should be followed by the language name. This is useful for include files that are included in several different languages. This option is not set by the user, it is always present during compilation.<br />
The following example starts a PHP open tag, but only if the file is being included in the PHP language:<br />
<group class="is_PHP"><element idref="e.php.short.open" /></group><br />
See more about this in the section '''Advanced group class/notclass values'''<br />
<br />
There are also a few global options that are hardcoded:<br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that for example attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
<br />
==== Limited regular expression support ====<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. You may use<br />
* a range of characters such as [a-z0-9;']<br />
* an inverted range such as [^0-9]<br />
* operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
* subpatterns such as ab(fg)?<br />
* the OR construction (foo|bar), but only within round braces<br />
<br />
Another limitation is that overlapping regular expressions result in undefined behavior. For example a construction like ([a-z]+p) will not work because p is part of the [a-z]+ so bluefish does not know when scanning a p if it is part of the [a-z]+ or it is the final p. <br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
<br />
<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. See also the section on hardcoded option names. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&gt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Debugging_Bluefish&diff=2748Debugging Bluefish2020-07-11T06:43:32Z<p>OlivierSessink: </p>
<hr />
<div>__TOC__<br />
<br />
= Providing information =<br />
<br />
In general: It is always a good idea to tell us your version of Bluefish and your version of '''GTK/Glib installed''' on your system, both can be found in the '''About''' menu. Also don't forget to mention the platform (Linux, OSX, Windows, FreeBSD, etc.) and it's version. If you have the possibility to test it on multiple computers with different platforms or versions this will really help to track down the problem. If you can reproduce a crash on some specific file, please send us the file too. The smaller the file, the easier for us to debug the issue.<br />
<br />
Crash reports / bugs are collected here: https://sourceforge.net/p/bluefish/tickets/<br />
<br />
= Specific crash information =<br />
<br />
== Debugging symbols ==<br />
<br />
To create a meaningful backtrace you'll need a binary with the debugging symbols attached. Otherwise your backtrace will contain a lot of question marks and won't be useful.<br />
<br />
=== Compile with debugging symbols from source ===<br />
<br />
[http://bfwiki.tellefsen.net/index.php/Getting_Bluefish#Downloading_the_source Get the source]. <br />
<br />
The Bluefish makefile strips the debugging symbols during the installation step ('''make install'''). In this case only re-compile the sources, run make install to install required files (in /usr/local/share/bluefish) and then run the resulting binary from the compile directory '''src/bluefish''' in the GNU Debugger.<br />
<br />
=== Install debugging symbols on Debian/Ubuntu systems ===<br />
<br />
For Debian and Ubuntu there might be packages available with debugging symbols. This package is called bluefish-dbg. Just install it the usual way, for example from the commandline with "apt-get install bluefish-dbg". If they are not available for your distribution or version you have to compile from source.<br />
<br />
You might need some more packages of this type: '''libc6-dbg''', '''libglib2.0-0-dbg''', '''libgtk-3-0-dbg''', '''libpcre3-dbg''', '''libxml2-dbg'''.<br />
<br />
== Run Bluefish in the debugger ==<br />
<br />
=== Create a meaningful backtrace ===<br />
<br />
To run Bluefish in the GNU Debugger (assuming you have just compiled it, and ran make install), use:<br />
<br />
gdb src/bluefish<br />
<br />
Then ('''(gdb)''' represents the gdb shell prompt!):<br />
<br />
(gdb) set logging on<br />
Copying output to gdb.txt.<br />
(gdb) r<br />
<br />
This will start bluefish. Now reproduce the crash and then create the backtrace:<br />
<br />
Program received signal SIGSEGV, Segmentation fault.<br />
...<br />
(gdb) bt full<br />
...<br />
(gdb) quit<br />
<br />
Now you'll find a file '''gdb.txt''' in the directory. [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Open a report in our BTS] and attach this file to the report. This is what a [[Backtrace Should Look Like]].<br />
<br />
=== Debugging a Gtk-Critical error ===<br />
<br />
If you set the environment variable '''G_DEBUG''' to ''fatal_warnings'', e.g.<br />
<br />
export G_DEBUG=fatal_warnings<br />
<br />
with bash, it should assert when there is an error. Then launch bluefish with gdb as told you above and you can get a backtrace.<br />
<br />
= debugging on windows =<br />
mypaint has a good tutorial: https://github.com/mypaint/mypaint/wiki/Debugging-crashes-on-Windows<br />
<br />
<br />
<br />
References: <references/></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Providing_information_on_crashes&diff=2747Providing information on crashes2020-07-11T06:42:57Z<p>OlivierSessink: /* Windows */</p>
<hr />
<div>= How to report information =<br />
<br />
Please create a bug report on:<br />
https://sourceforge.net/p/bluefish/tickets/<br />
<br />
Or subscribe to the bluefish community mailinglist.<br />
<br />
If this is all too complicated you can send an email to bluefish@bluefish.openoffice.nl<br />
<br />
= What to send =<br />
<br />
In general: It is always a good idea to tell us your version of Bluefish and your version of GTK/Glib installed on your system, both can be found in the About menu. Please copy/paste the information in ''Help->Build info'' <br />
<br />
Also don't forget to mention the platform (Linux, OSX, Windows, FreeBSD, etc.) and it's version (and for Linux the distribution). If you have the possibility to test it on multiple computers with different platforms or versions this will really help to track down the problem. If you can reproduce a crash on some specific file, please send us the file too. The smaller the file, the easier for us to debug the issue.<br />
<br />
= Linux =<br />
Linux has a wealth of tools to track down problems in software. Please have a look at <br />
https://bfwiki.tellefsen.net/index.php/Debugging_Bluefish<br />
for a detailed description on what is possible.<br />
<br />
= OSX =<br />
<br />
If Bluefish crashes on OSX there should be report generated in separate window. Please copy/paste this information (the backtrace) for thread 0 (on the top of the report) to text file and send it to the bluefish developers. Preferably create a bug report on https://sourceforge.net/p/bluefish/tickets/ and attach it as a text file.<br />
<br />
On OSX you can run Bluefish via terminal, that provides some debug output that might help to identify issue. Open terminal and type: /Applications/Bluefish.app/Contents/MacOS/bluefish (assuming that Bluefish is installed in the Applications folder). Please copy/paste the terminal output to a text file and attach it as well.<br />
<br />
= Windows =<br />
If you get a dialog "bluefish.exe has stopped working" you can click "view problems" which gives some rudimentary information. Since it is better than nothing, please provide it.<br />
<br />
In order to provide more information on Windows you can use the msys debugger, a good tutorial can be found here:<br />
https://github.com/mypaint/mypaint/wiki/Debugging-crashes-on-Windows</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Providing_information_on_crashes&diff=2746Providing information on crashes2020-07-11T06:38:14Z<p>OlivierSessink: </p>
<hr />
<div>= How to report information =<br />
<br />
Please create a bug report on:<br />
https://sourceforge.net/p/bluefish/tickets/<br />
<br />
Or subscribe to the bluefish community mailinglist.<br />
<br />
If this is all too complicated you can send an email to bluefish@bluefish.openoffice.nl<br />
<br />
= What to send =<br />
<br />
In general: It is always a good idea to tell us your version of Bluefish and your version of GTK/Glib installed on your system, both can be found in the About menu. Please copy/paste the information in ''Help->Build info'' <br />
<br />
Also don't forget to mention the platform (Linux, OSX, Windows, FreeBSD, etc.) and it's version (and for Linux the distribution). If you have the possibility to test it on multiple computers with different platforms or versions this will really help to track down the problem. If you can reproduce a crash on some specific file, please send us the file too. The smaller the file, the easier for us to debug the issue.<br />
<br />
= Linux =<br />
Linux has a wealth of tools to track down problems in software. Please have a look at <br />
https://bfwiki.tellefsen.net/index.php/Debugging_Bluefish<br />
for a detailed description on what is possible.<br />
<br />
= OSX =<br />
<br />
If Bluefish crashes on OSX there should be report generated in separate window. Please copy/paste this information (the backtrace) for thread 0 (on the top of the report) to text file and send it to the bluefish developers. Preferably create a bug report on https://sourceforge.net/p/bluefish/tickets/ and attach it as a text file.<br />
<br />
On OSX you can run Bluefish via terminal, that provides some debug output that might help to identify issue. Open terminal and type: /Applications/Bluefish.app/Contents/MacOS/bluefish (assuming that Bluefish is installed in the Applications folder). Please copy/paste the terminal output to a text file and attach it as well.<br />
<br />
= Windows =</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Providing_information_on_crashes&diff=2745Providing information on crashes2020-07-11T06:34:20Z<p>OlivierSessink: Created page with "= In general = Please create a bug report on: https://sourceforge.net/p/bluefish/tickets/ Or subscribe to the bluefish community mailinglist. If this is all too complicated..."</p>
<hr />
<div>= In general =<br />
<br />
Please create a bug report on:<br />
https://sourceforge.net/p/bluefish/tickets/<br />
<br />
Or subscribe to the bluefish community mailinglist.<br />
<br />
If this is all too complicated you can send an email to bluefish@bluefish.openoffice.nl<br />
<br />
= Linux =<br />
<br />
<br />
= OSX =<br />
<br />
If Bluefish crashes on OSX there should be report generated in separate window. Please copy/paste this information (the backtrace) for thread 0 (on the top of the report) to text file and send it to the bluefish developers. Preferably create a bug report on https://sourceforge.net/p/bluefish/tickets/ and attach it as a text file.<br />
<br />
On OSX you can run Bluefish via terminal, that provides some debug output that might help to identify issue. Open terminal and type: /Applications/Bluefish.app/Contents/MacOS/bluefish (assuming that Bluefish is installed in the Applications folder). Please copy/paste the terminal output to a text file and attach it as well.<br />
<br />
= Windows =</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Main_Page&diff=2744Main Page2020-07-11T06:30:06Z<p>OlivierSessink: /* Development / contributing */</p>
<hr />
<div>==Welcome to the Bluefish Wiki!==<br />
<br />
The official bluefish website is at http://bluefish.openoffice.nl<br />
<br />
See our [[Mailinglists]] to get in touch with the Bluefish community and developers. The honourable project leader is Olivier Sessink (olivier (at) bluefish.openoffice.nl). The wiki maintainer is Christian (bfwiki --a--tellefsen.net).<br />
<br />
=== Wiki user registration ===<br />
<br />
To register for an account, send me an email with your desired username to <tt>bfwiki--a--tellefsen.net</tt>.<br />
<br />
=== Help / documentation ===<br />
<br />
* [[Installing Bluefish]] / [[Compiling Bluefish from source]]<br />
* [[Hidden features]] <br />
* [[Keyboard shortcuts]]<br />
<br />
* [[Troubleshooting dll issues on windows]]<br />
* [[:Category:Manual 2|Bluefish 2 Manual project]]<br />
* [[Enabling Aspell Under MacOSX]]<br />
* [[Typing Japanese under MacOS X]]<br />
<br />
=== Development / contributing ===<br />
<br />
Recent activity:<br />
* [[Project Roadmap]]<br />
* [[Translations|Translation status]]<br />
* [[Providing information on crashes]]<br />
* [[Debugging Bluefish]]<br />
* [[Writing language definition files]]<br />
<br />
<br />
* [[CommunityTools]]<br />
* [[Getting Bluefish]]<br />
* [[Sending Patches]]<br />
* [[Setting up a Windows Build Environment]] [[Installation d'un environnement de compilation Windows|(français)]]<br />
* [[Using File Type Icons in Bluefish 2]]<br />
* [[Building a native (no X11) MacOSX binary]]<br />
<br />
Still useful:<br />
<br />
* [[Man 1 index|The Bluefish 1 Manual]]<br />
* [[Compiling Under MacOS X]]<br />
* [[Backtrace Under Mac OS X]]<br />
* [[Customization For MacOS X]]<br />
* [[Compiling Under Cygwin]]<br />
<br />
=== Old stuff, mostly outdated ===<br />
* [[Syntax Highlighting Colours]] - default colors for all languages<br />
* [[Scanner]] - Bluefish text widget with scanning features<br />
* [[Manual]] -- Just so people can work out whos doing what (Now being Maintained by Scott White)<br />
* [[Function Reference 2]] - new function reference for Bluefish (or should we call it Information Center ?)<br />
* Search and Replace dialog<br />
* [[Reproducable Bugs]]<br />
* [[Preferences Refactor]] - Changes and removals on the Prefs Dialog<br />
* [[Feature Requests]]<br />
* [[ToDo List]]<br />
* [[Plugins]]<br />
* [[Current Plans]] from all developers<br />
* [[Gnome HIG]] compliance<br />
* [[Cvs Activity]]<br />
* [[Project Management]] - Olivier<br />
* [[Function Reference]] - implemented already, but we need more references for python, perl etc.<br />
* [[Old stuff, Bookmarks]]<br />
* [[Downloading From CVS]]<br />
* [[Compiling Manual]]<br />
This Wiki is maintained by the Bluefish community. If you want to help to contribute in any way, please contact us on the [[Mailinglists|bluefish mailinglist]]. If you want to help translate Bluefish, have a look at [[Translations]].</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Compiling_Bluefish_from_source&diff=2743Compiling Bluefish from source2020-02-18T21:26:13Z<p>OlivierSessink: /* Building (assumes required packages have been installed) */</p>
<hr />
<div>= Compiling bluefish from source tarballs =<br />
<br />
== installing the requirements ==<br />
<br />
Build requirements:<br />
* a C compiler (for example gcc or clang-gcc)<br />
* gnu make<br />
<br />
Library / header file requirements:<br />
* gtk+ 2 or 3 development files (sometimes called libgtk2.0-dev or libgtk2-devel, or libgtk-3-dev)<br />
* libxml2 development files (sometimes called libxml2-dev or libxml2-devel)<br />
<br />
Optional libraries / header files:<br />
* libenchant + development files (for spell checking, libenchant-dev)<br />
* libgucharmap + development files (for the character map side pane plugin, libgucharmap-dev)<br />
* python development files (python-dev or python-devel)<br />
<br />
=== Debian and Ubuntu packages required ===<br />
* automake<br />
* autoconf<br />
* make<br />
* libtool<br />
* intltool<br />
* libgtk-3-dev<br />
* libxml2-dev<br />
and optional<br />
* libenchant-dev<br />
* libgucharmap-2-90-dev<br />
* python-dev<br />
<br />
== Getting and compiling ==<br />
* get the latest source from http://www.bennewitz.com/bluefish/stable/source/<br />
* unpack <br />
** for a gzipped file '''tar -xzf bluefish-2.2.xxxx.tar.gz'''<br />
** for a bzipped file '''tar -xjf bluefish-2.2.xxxx.tar.bz2'''<br />
* '''cd bluefish-2.2.xxxx'''<br />
* run '''./configure'''<br />
* run '''make'''<br />
* switch to root and run '''make install'''<br />
<br />
= Compiling bluefish straight from subversion =<br />
=== Building (assumes required packages have been installed) ===<br />
svn checkout svn://svn.code.sf.net/p/bluefish/code/trunk bluefish<br />
cd bluefish<br />
./autogen.sh<br />
./configure<br />
make<br />
sudo make install<br />
<br />
=== Debian and Ubuntu packages required to build from subversion ===<br />
* libtool<br />
* intltool<br />
* automake<br />
* autoconf<br />
* make<br />
* libgtk-3-dev<br />
* libenchant-dev<br />
* libgucharmap-2-90-dev<br />
* libxml2-dev<br />
* subversion<br />
* python-dev</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Compiling_Bluefish_from_source&diff=2742Compiling Bluefish from source2020-02-18T21:25:51Z<p>OlivierSessink: </p>
<hr />
<div>= Compiling bluefish from source tarballs =<br />
<br />
== installing the requirements ==<br />
<br />
Build requirements:<br />
* a C compiler (for example gcc or clang-gcc)<br />
* gnu make<br />
<br />
Library / header file requirements:<br />
* gtk+ 2 or 3 development files (sometimes called libgtk2.0-dev or libgtk2-devel, or libgtk-3-dev)<br />
* libxml2 development files (sometimes called libxml2-dev or libxml2-devel)<br />
<br />
Optional libraries / header files:<br />
* libenchant + development files (for spell checking, libenchant-dev)<br />
* libgucharmap + development files (for the character map side pane plugin, libgucharmap-dev)<br />
* python development files (python-dev or python-devel)<br />
<br />
=== Debian and Ubuntu packages required ===<br />
* automake<br />
* autoconf<br />
* make<br />
* libtool<br />
* intltool<br />
* libgtk-3-dev<br />
* libxml2-dev<br />
and optional<br />
* libenchant-dev<br />
* libgucharmap-2-90-dev<br />
* python-dev<br />
<br />
== Getting and compiling ==<br />
* get the latest source from http://www.bennewitz.com/bluefish/stable/source/<br />
* unpack <br />
** for a gzipped file '''tar -xzf bluefish-2.2.xxxx.tar.gz'''<br />
** for a bzipped file '''tar -xjf bluefish-2.2.xxxx.tar.bz2'''<br />
* '''cd bluefish-2.2.xxxx'''<br />
* run '''./configure'''<br />
* run '''make'''<br />
* switch to root and run '''make install'''<br />
<br />
= Compiling bluefish straight from subversion =<br />
=== Building (assumes required packages have been installed) ===<br />
svn checkout svn://svn.code.sf.net/p/bluefish/code/trunk bluefish-code<br />
cd bluefish<br />
./autogen.sh<br />
./configure<br />
make<br />
sudo make install<br />
<br />
<br />
=== Debian and Ubuntu packages required to build from subversion ===<br />
* libtool<br />
* intltool<br />
* automake<br />
* autoconf<br />
* make<br />
* libgtk-3-dev<br />
* libenchant-dev<br />
* libgucharmap-2-90-dev<br />
* libxml2-dev<br />
* subversion<br />
* python-dev</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2741Writing language definition files2019-04-12T18:09:29Z<p>OlivierSessink: /* The element tag in the definition section */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names that can be used in the language file:<br />
<br />
The '_foldable' suffix is hardcoded in bluefish. It should be followed by block_name that is used in the language file somewhere. The attribute block_name can be in an <element> tag. In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. <br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
The 'is_' suffix is hardcoded in bluefish. It should be followed by the language name. This is useful for include files that are included in several different languages. This option is not set by the user, it is always present during compilation.<br />
The following example starts a PHP open tag, but only if the file is being included in the PHP language:<br />
<group class="is_PHP"><element idref="e.php.short.open" /></group><br />
See more about this in the section '''Advanced group class/notclass values'''<br />
<br />
There are also a few global options that are hardcoded:<br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that for example attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
<br />
==== Limited regular expression support ====<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. You may use<br />
* a range of characters such as [a-z0-9;']<br />
* an inverted range such as [^0-9]<br />
* operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
* subpatterns such as ab(fg)?<br />
* the OR construction (foo|bar), but only within round braces<br />
<br />
Another limitation is that overlapping regular expressions result in undefined behavior. For example a construction like ([a-z]+p) will not work because p is part of the [a-z]+ so bluefish does not know when scanning a p if it is part of the [a-z]+ or it is the final p. <br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
<br />
<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. See also the section on hardcoded option names. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2740Writing language definition files2019-04-12T17:39:54Z<p>OlivierSessink: /* The element tag in the definition section */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names that can be used in the language file:<br />
<br />
The '_foldable' suffix is hardcoded in bluefish. It should be followed by block_name that is used in the language file somewhere. The attribute block_name can be in an <element> tag. In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. <br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
The 'is_' suffix is hardcoded in bluefish. It should be followed by the language name. This is useful for include files that are included in several different languages. This option is not set by the user, it is always present during compilation.<br />
The following example starts a PHP open tag, but only if the file is being included in the PHP language:<br />
<group class="is_PHP"><element idref="e.php.short.open" /></group><br />
See more about this in the section '''Advanced group class/notclass values'''<br />
<br />
There are also a few global options that are hardcoded:<br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that for example attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. you may use<br />
* a range of characters such as [a-z0-9;']<br />
* an inverted range such as [^0-9]<br />
* operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
* subpatterns such as ab(fg)?<br />
* the OR construction (foo|bar), but only within round braces<br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. See also the section on hardcoded option names. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Mailinglists&diff=2732Mailinglists2017-05-01T19:51:37Z<p>OlivierSessink: </p>
<hr />
<div>We currently have two mailinglists available:<br />
<br />
=== Bluefish community ===<br />
<br />
General discussion on use and development.<br />
<br />
https://lists.sourceforge.net/lists/listinfo/bluefish-community<br />
<br />
=== Bluefish svn ===<br />
<br />
Code commits to subversion<br />
<br />
https://lists.sourceforge.net/lists/listinfo/bluefish-svn</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Debugging_Bluefish&diff=2731Debugging Bluefish2017-05-01T19:48:39Z<p>OlivierSessink: /* Create a meaningful backtrace */</p>
<hr />
<div>__TOC__<br />
<br />
= Providing information =<br />
<br />
In general: It is always a good idea to tell us your version of Bluefish and your version of '''GTK/Glib installed''' on your system, both can be found in the '''About''' menu. Also don't forget to mention the platform (Linux, OSX, Windows, FreeBSD, etc.) and it's version. If you have the possibility to test it on multiple computers with different platforms or versions this will really help to track down the problem. If you can reproduce a crash on some specific file, please send us the file too. The smaller the file, the easier for us to debug the issue.<br />
<br />
Crash reports / bugs are collected here: https://bugzilla.gnome.org/page.cgi?id=browse.html&product=bluefish<br />
<br />
= Specific crash information =<br />
<br />
== Debugging symbols ==<br />
<br />
To create a meaningful backtrace you'll need a binary with the debugging symbols attached. Otherwise your backtrace will contain a lot of question marks and won't be useful.<br />
<br />
=== Compile with debugging symbols from source ===<br />
<br />
[http://bfwiki.tellefsen.net/index.php/Getting_Bluefish#Downloading_the_source Get the source]. <br />
<br />
The Bluefish makefile strips the debugging symbols during the installation step ('''make install'''). In this case only re-compile the sources, run make install to install required files (in /usr/local/share/bluefish) and then run the resulting binary from the compile directory '''src/bluefish''' in the GNU Debugger.<br />
<br />
=== Install debugging symbols on Debian/Ubuntu systems ===<br />
<br />
For Debian and Ubuntu there might be packages available with debugging symbols. This package is called bluefish-dbg. Just install it the usual way, for example from the commandline with "apt-get install bluefish-dbg". If they are not available for your distribution or version you have to compile from source.<br />
<br />
You might need some more packages of this type: '''libc6-dbg''', '''libglib2.0-0-dbg''', '''libgtk-3-0-dbg''', '''libpcre3-dbg''', '''libxml2-dbg'''.<br />
<br />
== Run Bluefish in the debugger ==<br />
<br />
=== Create a meaningful backtrace ===<br />
<br />
To run Bluefish in the GNU Debugger (assuming you have just compiled it, and ran make install), use:<br />
<br />
gdb src/bluefish<br />
<br />
Then ('''(gdb)''' represents the gdb shell prompt!):<br />
<br />
(gdb) set logging on<br />
Copying output to gdb.txt.<br />
(gdb) r<br />
<br />
This will start bluefish. Now reproduce the crash and then create the backtrace:<br />
<br />
Program received signal SIGSEGV, Segmentation fault.<br />
...<br />
(gdb) bt full<br />
...<br />
(gdb) quit<br />
<br />
Now you'll find a file '''gdb.txt''' in the directory. [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Open a report in our BTS] and attach this file to the report. This is what a [[Backtrace Should Look Like]].<br />
<br />
=== Debugging a Gtk-Critical error ===<br />
<br />
If you set the environment variable '''G_DEBUG''' to ''fatal_warnings'', e.g.<br />
<br />
export G_DEBUG=fatal_warnings<br />
<br />
with bash, it should assert when there is an error. Then launch bluefish with gdb as told you above and you can get a backtrace.<br />
<br />
= debugging on windows =<br />
mypaint has a good tutorial: https://github.com/mypaint/mypaint/wiki/Debugging-crashes-on-Windows<br />
<br />
<br />
<br />
References: <references/></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Debugging_Bluefish&diff=2730Debugging Bluefish2017-05-01T19:47:56Z<p>OlivierSessink: /* Install debugging symbols on Debian/Ubuntu systems */</p>
<hr />
<div>__TOC__<br />
<br />
= Providing information =<br />
<br />
In general: It is always a good idea to tell us your version of Bluefish and your version of '''GTK/Glib installed''' on your system, both can be found in the '''About''' menu. Also don't forget to mention the platform (Linux, OSX, Windows, FreeBSD, etc.) and it's version. If you have the possibility to test it on multiple computers with different platforms or versions this will really help to track down the problem. If you can reproduce a crash on some specific file, please send us the file too. The smaller the file, the easier for us to debug the issue.<br />
<br />
Crash reports / bugs are collected here: https://bugzilla.gnome.org/page.cgi?id=browse.html&product=bluefish<br />
<br />
= Specific crash information =<br />
<br />
== Debugging symbols ==<br />
<br />
To create a meaningful backtrace you'll need a binary with the debugging symbols attached. Otherwise your backtrace will contain a lot of question marks and won't be useful.<br />
<br />
=== Compile with debugging symbols from source ===<br />
<br />
[http://bfwiki.tellefsen.net/index.php/Getting_Bluefish#Downloading_the_source Get the source]. <br />
<br />
The Bluefish makefile strips the debugging symbols during the installation step ('''make install'''). In this case only re-compile the sources, run make install to install required files (in /usr/local/share/bluefish) and then run the resulting binary from the compile directory '''src/bluefish''' in the GNU Debugger.<br />
<br />
=== Install debugging symbols on Debian/Ubuntu systems ===<br />
<br />
For Debian and Ubuntu there might be packages available with debugging symbols. This package is called bluefish-dbg. Just install it the usual way, for example from the commandline with "apt-get install bluefish-dbg". If they are not available for your distribution or version you have to compile from source.<br />
<br />
You might need some more packages of this type: '''libc6-dbg''', '''libglib2.0-0-dbg''', '''libgtk-3-0-dbg''', '''libpcre3-dbg''', '''libxml2-dbg'''.<br />
<br />
== Run Bluefish in the debugger ==<br />
<br />
=== Create a meaningful backtrace ===<br />
<br />
To run Bluefish in the GNU Debugger, use:<br />
<br />
gdb bluefish<br />
<br />
or for the '''1.0 series''' (see above):<br />
<br />
gdb src/bluefish<br />
<br />
Then ('''(gdb)''' represents the gdb shell prompt!):<br />
<br />
(gdb) set logging on<br />
Copying output to gdb.txt.<br />
(gdb) r<br />
<br />
This will start bluefish. Now reproduce the crash and then create the backtrace:<br />
<br />
Program received signal SIGSEGV, Segmentation fault.<br />
...<br />
(gdb) bt full<br />
...<br />
(gdb) quit<br />
<br />
Now you'll find a file '''gdb.txt''' in the directory. [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Open a report in our BTS] and attach this file to the report. This is what a [[Backtrace Should Look Like]].<br />
<br />
=== Debugging a Gtk-Critical error ===<br />
<br />
If you set the environment variable '''G_DEBUG''' to ''fatal_warnings'', e.g.<br />
<br />
export G_DEBUG=fatal_warnings<br />
<br />
with bash, it should assert when there is an error. Then launch bluefish with gdb as told you above and you can get a backtrace.<br />
<br />
= debugging on windows =<br />
mypaint has a good tutorial: https://github.com/mypaint/mypaint/wiki/Debugging-crashes-on-Windows<br />
<br />
<br />
<br />
References: <references/></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Debugging_Bluefish&diff=2729Debugging Bluefish2017-05-01T19:46:37Z<p>OlivierSessink: /* Compile with debugging symbols from source */</p>
<hr />
<div>__TOC__<br />
<br />
= Providing information =<br />
<br />
In general: It is always a good idea to tell us your version of Bluefish and your version of '''GTK/Glib installed''' on your system, both can be found in the '''About''' menu. Also don't forget to mention the platform (Linux, OSX, Windows, FreeBSD, etc.) and it's version. If you have the possibility to test it on multiple computers with different platforms or versions this will really help to track down the problem. If you can reproduce a crash on some specific file, please send us the file too. The smaller the file, the easier for us to debug the issue.<br />
<br />
Crash reports / bugs are collected here: https://bugzilla.gnome.org/page.cgi?id=browse.html&product=bluefish<br />
<br />
= Specific crash information =<br />
<br />
== Debugging symbols ==<br />
<br />
To create a meaningful backtrace you'll need a binary with the debugging symbols attached. Otherwise your backtrace will contain a lot of question marks and won't be useful.<br />
<br />
=== Compile with debugging symbols from source ===<br />
<br />
[http://bfwiki.tellefsen.net/index.php/Getting_Bluefish#Downloading_the_source Get the source]. <br />
<br />
The Bluefish makefile strips the debugging symbols during the installation step ('''make install'''). In this case only re-compile the sources, run make install to install required files (in /usr/local/share/bluefish) and then run the resulting binary from the compile directory '''src/bluefish''' in the GNU Debugger.<br />
<br />
=== Install debugging symbols on Debian/Ubuntu systems ===<br />
<br />
For Debian and Ubuntu there are packages available with debugging symbols. This package is called bluefish-dbg. Just install it the usual way, for example from the commandline with "apt-get install bluefish-dbg"<br />
<br />
You might need some more packages of this type: '''libc6-dbg''', '''libglib2.0-0-dbg''', '''libgtk-3-0-dbg''', '''libpcre3-dbg''', '''libxml2-dbg'''.<br />
<br />
== Run Bluefish in the debugger ==<br />
<br />
=== Create a meaningful backtrace ===<br />
<br />
To run Bluefish in the GNU Debugger, use:<br />
<br />
gdb bluefish<br />
<br />
or for the '''1.0 series''' (see above):<br />
<br />
gdb src/bluefish<br />
<br />
Then ('''(gdb)''' represents the gdb shell prompt!):<br />
<br />
(gdb) set logging on<br />
Copying output to gdb.txt.<br />
(gdb) r<br />
<br />
This will start bluefish. Now reproduce the crash and then create the backtrace:<br />
<br />
Program received signal SIGSEGV, Segmentation fault.<br />
...<br />
(gdb) bt full<br />
...<br />
(gdb) quit<br />
<br />
Now you'll find a file '''gdb.txt''' in the directory. [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Open a report in our BTS] and attach this file to the report. This is what a [[Backtrace Should Look Like]].<br />
<br />
=== Debugging a Gtk-Critical error ===<br />
<br />
If you set the environment variable '''G_DEBUG''' to ''fatal_warnings'', e.g.<br />
<br />
export G_DEBUG=fatal_warnings<br />
<br />
with bash, it should assert when there is an error. Then launch bluefish with gdb as told you above and you can get a backtrace.<br />
<br />
= debugging on windows =<br />
mypaint has a good tutorial: https://github.com/mypaint/mypaint/wiki/Debugging-crashes-on-Windows<br />
<br />
<br />
<br />
References: <references/></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Debugging_Bluefish&diff=2725Debugging Bluefish2017-01-20T12:19:05Z<p>OlivierSessink: </p>
<hr />
<div>__TOC__<br />
<br />
= Providing information =<br />
<br />
In general: It is always a good idea to tell us your version of Bluefish and your version of '''GTK/Glib installed''' on your system, both can be found in the '''About''' menu. Also don't forget to mention the platform (Linux, OSX, Windows, FreeBSD, etc.) and it's version. If you have the possibility to test it on multiple computers with different platforms or versions this will really help to track down the problem. If you can reproduce a crash on some specific file, please send us the file too. The smaller the file, the easier for us to debug the issue.<br />
<br />
Crash reports / bugs are collected here: https://bugzilla.gnome.org/page.cgi?id=browse.html&product=bluefish<br />
<br />
= Specific crash information =<br />
<br />
== Debugging symbols ==<br />
<br />
To create a meaningful backtrace you'll need a binary with the debugging symbols attached. Otherwise your backtrace will contain a lot of question marks and won't be useful.<br />
<br />
=== Compile with debugging symbols from source ===<br />
<br />
[http://bfwiki.tellefsen.net/index.php/Getting_Bluefish#Downloading_the_source Get the source]. To compile it with debugging symbols, CFLAGS must contain '''-g'''. You should also use the '''-O0''' optimization flag there.<br /><br />
<tt>$ ./configure CFLAGS="-g -O0" && make</tt><br />
<br />
For more information about compiling from source, see [[Compiling Bluefish from source]].<br />
<br />
The stable version of bluefish, namely 2.2.X at the time of writing, currently strips the debugging symbols during the installation step ('''make install'''). In this case only re-compile the sources and run the resulting binary '''src/bluefish''' in the GNU Debugger.<br />
<br />
=== Install debugging symbols on Debian/Ubuntu systems ===<br />
<br />
For Debian and Ubuntu there are packages available with debugging symbols. This package is called bluefish-dbg. Just install it the usual way, for example from the commandline with "apt-get install bluefish-dbg"<br />
<br />
You might need some more packages of this type: '''libc6-dbg''', '''libglib2.0-0-dbg''', '''libgtk-3-0-dbg''', '''libpcre3-dbg''', '''libxml2-dbg'''.<br />
<br />
== Run Bluefish in the debugger ==<br />
<br />
=== Create a meaningful backtrace ===<br />
<br />
To run Bluefish in the GNU Debugger, use:<br />
<br />
gdb bluefish<br />
<br />
or for the '''1.0 series''' (see above):<br />
<br />
gdb src/bluefish<br />
<br />
Then ('''(gdb)''' represents the gdb shell prompt!):<br />
<br />
(gdb) set logging on<br />
Copying output to gdb.txt.<br />
(gdb) r<br />
<br />
This will start bluefish. Now reproduce the crash and then create the backtrace:<br />
<br />
Program received signal SIGSEGV, Segmentation fault.<br />
...<br />
(gdb) bt full<br />
...<br />
(gdb) quit<br />
<br />
Now you'll find a file '''gdb.txt''' in the directory. [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Open a report in our BTS] and attach this file to the report. This is what a [[Backtrace Should Look Like]].<br />
<br />
=== Debugging a Gtk-Critical error ===<br />
<br />
If you set the environment variable '''G_DEBUG''' to ''fatal_warnings'', e.g.<br />
<br />
export G_DEBUG=fatal_warnings<br />
<br />
with bash, it should assert when there is an error. Then launch bluefish with gdb as told you above and you can get a backtrace.<br />
<br />
= debugging on windows =<br />
mypaint has a good tutorial: https://github.com/mypaint/mypaint/wiki/Debugging-crashes-on-Windows<br />
<br />
<br />
<br />
References: <references/></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Installing_Bluefish&diff=2724Installing Bluefish2017-01-19T14:31:28Z<p>OlivierSessink: /* Installing Bluefish on Fedora Linux */</p>
<hr />
<div>= Installing Bluefish on Debian GNU/Linux =<br />
<br />
== Installing the release that is part of Debian / Ubuntu / Mint / etc. ==<br />
<br />
Use<br />
<br />
sudo apt-get install bluefish<br />
sudo aptitude install bluefish<br />
<br />
or any other frontend for the package manager such as synaptic or simply "add / remove programs".<br />
<br />
== Installing the very latest release on Debian ==<br />
<br />
=== Installing the very latest release on Debian 8 (Jessie/Stable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/jessie-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian jessie-backports main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian stable-backports main<br />
<br />
And install the package via:<br />
<br />
apt-get -t jessie-backports install bluefish<br />
<br />
Report any bugs to the Debian bugtracker.<br />
<br />
=== Installing the very latest release on Debian 7.0 (Wheezy/Oldstable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/wheezy-backports-sloppy/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian wheezy-backports-sloppy main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian oldstable-backports-sloppy main<br />
<br />
And install the package via:<br />
<br />
apt-get -t wheezy-backports-sloppy install bluefish<br />
<br />
Report any bugs to the Debian bugtracker.<br />
<br />
=== Installing the very latest release on Debian 6.0 (Squeeze/Oldoldstable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/squeeze-backports-sloppy/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports squeeze-backports-sloppy main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports oldoldstable-backports-sloppy main<br />
<br />
And install the package via:<br />
<br />
apt-get -t squeeze-backports-sloppy install bluefish<br />
<br />
This version is built with the GTK+ 2 libraries. Report any bugs to the Debian bugtracker.<br />
<br />
== Installing the very latest on Ubuntu Linux ==<br />
<br />
You'll find recent packages of '''bluefish''' in [https://launchpad.net/~klaus-vormweg/+archive/bluefish the Bluefish PPA maintained by Klaus Vormweg]. Follow the instructions given there to add this repository. Then '''bluefish''' can be updated to its latest release:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
=== Removing obsolete debian.wgdd.de entries from sources.list ===<br />
<br />
The http://debian.wgdd.de/ repository no longer provides packages of bluefish. The above steps make the following entries to either ''/etc/apt/sources.list'' or ''/etc/apt/sources.list.d/debian.wgdd.de_*.list'' or any other file in ''/etc/apt/sources.list.d/'' obsolete. You can safely remove any references to the http://debian.wgdd.de repository, that may look like these:<br />
<br />
deb http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb-src http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb http://debian.wgdd.de/debian stable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian stable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb-src http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb http://debian.wgdd.de/debian oldstable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian oldstable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
deb-src http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
<br />
and update your system:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Also the '''wgdd-archive-keyring''' package then is obsolete together with the repository keyring. If you have the package installed, do:<br />
<br />
sudo apt-get autoremove --purge wgdd-archive-keyring<br />
<br />
... or if you only had the key:<br />
<br />
sudo apt-key del E394D996<br />
<br />
= Installing Bluefish on Fedora Linux =<br />
<br />
=== Installing the version distributed by Fedora ===<br />
<br />
dnf install bluefish<br />
<br />
=== Installing the very latest on Fedora with yum ===<br />
<br />
To enable a bluefish-release yum repository download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-release.repo bluefish-release.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19, 20 and 21. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br/><br />
<br />
=== Installing development versions on Fedora with yum ===<br />
<br />
While care is taken to keep development versions very stable and usable, development versions may crash, contain data eating bugs and incomplete features.<br/><br />
Please report any bugs you might find in [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Bluefish bugzilla]<br/><br />
<br />
If you wish to test the bleeding edge versions of Bluefish currently under development download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-svn.repo bluefish-svn.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19, 20 and 21. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br />
<br />
=== Browsable Yum repo's for Fedora ===<br />
<br />
These pages were created using repoview.<br />
<br />
Fedora 19 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/x86_64/repoview/ x86_64]<br />
<br />
Fedora 20 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/x86_64/repoview/ x86_64]<br />
<br />
Fedora 21 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/21/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/21/x86_64/repoview/ x86_64]<br />
<br />
= Installing Bluefish on RHEL/CentOS 6.5 =<br />
<br />
=== Installing the very latest on RHEL/CentOS 6.5 ===<br />
<br />
Bluefish packages for RHEL/CentOS 6.5 are available at the links below for i386 and x86_64.<br/><br />
These packages require version 6.5. Previous versions prior to 6.5 had GTK+ 2.18.x.<br/><br />
RHEL/CentOS 6.5 has GTK+ 2.20.x which is the minimum version required to build current versions of Bluefish.<br />
<br />
All packages are built using mock. All packages are signed with this gpg [http://bluefish.linuxexperience.net/downloads/fedora/RPM-GPG-KEY-bluefish-svn.asc key].<br />
<br />
<br />
Required for RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-2.2.7-1.el6.i686.rpm bluefish-2.2.7-1.el6.i686.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-shared-data-2.2.7-1.el6.noarch.rpm bluefish-shared-data-2.2.7-1.el6.noarch.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-2.2.7-1.el6.x86_64.rpm bluefish-2.2.7-1.el6.x86_64.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-shared-data-2.2.7-1.el6.noarch.rpm bluefish-shared-data-2.2.7-1.el6.noarch.rpm]<br />
<br />
Optional debug info RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/i386/bluefish-debuginfo-2.2.7-1.el6.i686.rpm bluefish-debuginfo-2.2.7-1.el6.i686.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/x86_64/bluefish-debuginfo-2.2.7-1.el6.x86_64.rpm bluefish-debuginfo-2.2.7-1.el6.x86_64.rpm]<br />
<br />
= Installing Bluefish on openSUSE =<br />
<br />
Bluefish is available in the main repository. Launch YaST and search for "bluefish" to find and select the appropriate package to install.<br />
<br />
This process is also automated through 1-Click-Install on the openSUSE Build Service: https://software.opensuse.org/package/bluefish<br />
<br />
= Installing Bluefish on AltLinux =<br />
<br />
<br />
= Installing Bluefish on Slackware =<br />
<br />
= Installing Bluefish on Mac OS X =<br />
<br />
Download the latest version installer from http://www.bennewitz.com/bluefish/stable/binaries/macosx/, open it and drag the bluefish icon onto Applications.<br />
<br />
In Mavericks there is a system setting called ''Gatekeeper'' that only allows you to install packages from Apple-identified developers. Bluefish is not distributed through the Apple app store, so you will have to workaround that setting.<br />
<br />
Use the contextual menu (e.g. secondary-click button), and you'll see a menu with "Open" in it.<br />
This will present you with a dialogue box, asking you for permission to run the software.<br />
You will only be asked this the first time.<br />
<br />
Alternatively, the ''Gatekeeper'' setting can be disabled. For information, see: <br />
https://kb.wisc.edu/helpdesk/page.php?id=25443 or http://support.apple.com/kb/ht5290<br />
<br />
= Installing Bluefish on Windows XP or newer =<br />
<br />
=== Installing with internet connection ===<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
The installer will require internet access to download GTK+ and any spell check dictionaries. Please note that the internet-enabled setup may fail if the installer is run from a network share. See below for instructions for internet-less installation.<br />
<br />
==== Installing without Internet Access ====<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
Download the GTK+ 2.24.8 installer (from the gtk-win project): <br />
http://downloads.sourceforge.net/gtk-win/gtk2-runtime-2.24.8-2011-12-03-ash.exe?download<br />
<br />
Download any language dictionaries you wish to be able to install: <br />
http://www.muleslow.net/files/aspell/lang/<br />
<br />
Place the files in a new directory named 'redist' in the same directory as the Bluefish installer.<br />
e.x.<br />
Bluefish\<br />
Bluefish\Bluefish-2.2.7-setup.exe<br />
Bluefish\redist\gtk2-runtime-2.24.8-2011-12-03-ash.exe<br />
Bluefish\redist\aspell6-en-7.1-0.tbz2<br />
<br />
The installer will fall back on downloading the files if they are not found in the redist folder, or if the checksum of the local copy is invalid.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Installing_Bluefish&diff=2693Installing Bluefish2016-01-27T20:08:54Z<p>OlivierSessink: /* Installing 2.2.7 */</p>
<hr />
<div>= Installing Bluefish on Debian GNU/Linux =<br />
<br />
== Installing the release that is part of Debian / Ubuntu / Mint / etc. ==<br />
<br />
Use<br />
<br />
sudo apt-get install bluefish<br />
sudo aptitude install bluefish<br />
<br />
or any other frontend for the package manager such as synaptic or simply "add / remove programs".<br />
<br />
== Installing the very latest release on Debian ==<br />
<br />
=== Installing the very latest release on Debian 8 (Jessie/Stable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/jessie-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian jessie-backports main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian stable-backports main<br />
<br />
And install the package via:<br />
<br />
apt-get -t jessie-backports install bluefish<br />
<br />
Report any bugs to the Debian bugtracker.<br />
<br />
=== Installing the very latest release on Debian 7.0 (Wheezy/Oldstable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/wheezy-backports-sloppy/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian wheezy-backports-sloppy main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian oldstable-backports-sloppy main<br />
<br />
And install the package via:<br />
<br />
apt-get -t wheezy-backports-sloppy install bluefish<br />
<br />
Report any bugs to the Debian bugtracker.<br />
<br />
=== Installing the very latest release on Debian 6.0 (Squeeze/Oldoldstable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/squeeze-backports-sloppy/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports squeeze-backports-sloppy main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports oldoldstable-backports-sloppy main<br />
<br />
And install the package via:<br />
<br />
apt-get -t squeeze-backports-sloppy install bluefish<br />
<br />
This version is built with the GTK+ 2 libraries. Report any bugs to the Debian bugtracker.<br />
<br />
== Installing the very latest on Ubuntu Linux ==<br />
<br />
You'll find recent packages of '''bluefish''' in [https://launchpad.net/~klaus-vormweg/+archive/bluefish the Bluefish PPA maintained by Klaus Vormweg]. Follow the instructions given there to add this repository. Then '''bluefish''' can be updated to its latest release:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
=== Removing obsolete debian.wgdd.de entries from sources.list ===<br />
<br />
The http://debian.wgdd.de/ repository no longer provides packages of bluefish. The above steps make the following entries to either ''/etc/apt/sources.list'' or ''/etc/apt/sources.list.d/debian.wgdd.de_*.list'' or any other file in ''/etc/apt/sources.list.d/'' obsolete. You can safely remove any references to the http://debian.wgdd.de repository, that may look like these:<br />
<br />
deb http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb-src http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb http://debian.wgdd.de/debian stable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian stable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb-src http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb http://debian.wgdd.de/debian oldstable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian oldstable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
deb-src http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
<br />
and update your system:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Also the '''wgdd-archive-keyring''' package then is obsolete together with the repository keyring. If you have the package installed, do:<br />
<br />
sudo apt-get autoremove --purge wgdd-archive-keyring<br />
<br />
... or if you only had the key:<br />
<br />
sudo apt-key del E394D996<br />
<br />
= Installing Bluefish on Fedora Linux =<br />
<br />
=== Installing the version distributed by Fedora ===<br />
<br />
yum install bluefish<br />
<br />
=== Installing the very latest on Fedora with yum ===<br />
<br />
To enable a bluefish-release yum repository download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-release.repo bluefish-release.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19, 20 and 21. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br/><br />
<br />
=== Installing development versions on Fedora with yum ===<br />
<br />
While care is taken to keep development versions very stable and usable, development versions may crash, contain data eating bugs and incomplete features.<br/><br />
Please report any bugs you might find in [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Bluefish bugzilla]<br/><br />
<br />
If you wish to test the bleeding edge versions of Bluefish currently under development download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-svn.repo bluefish-svn.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19, 20 and 21. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br />
<br />
=== Browsable Yum repo's for Fedora ===<br />
<br />
These pages were created using repoview.<br />
<br />
Fedora 19 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/x86_64/repoview/ x86_64]<br />
<br />
Fedora 20 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/x86_64/repoview/ x86_64]<br />
<br />
Fedora 21 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/21/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/21/x86_64/repoview/ x86_64]<br />
<br />
= Installing Bluefish on RHEL/CentOS 6.5 =<br />
<br />
=== Installing the very latest on RHEL/CentOS 6.5 ===<br />
<br />
Bluefish packages for RHEL/CentOS 6.5 are available at the links below for i386 and x86_64.<br/><br />
These packages require version 6.5. Previous versions prior to 6.5 had GTK+ 2.18.x.<br/><br />
RHEL/CentOS 6.5 has GTK+ 2.20.x which is the minimum version required to build current versions of Bluefish.<br />
<br />
All packages are built using mock. All packages are signed with this gpg [http://bluefish.linuxexperience.net/downloads/fedora/RPM-GPG-KEY-bluefish-svn.asc key].<br />
<br />
<br />
Required for RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-2.2.7-1.el6.i686.rpm bluefish-2.2.7-1.el6.i686.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-shared-data-2.2.7-1.el6.noarch.rpm bluefish-shared-data-2.2.7-1.el6.noarch.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-2.2.7-1.el6.x86_64.rpm bluefish-2.2.7-1.el6.x86_64.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-shared-data-2.2.7-1.el6.noarch.rpm bluefish-shared-data-2.2.7-1.el6.noarch.rpm]<br />
<br />
Optional debug info RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/i386/bluefish-debuginfo-2.2.7-1.el6.i686.rpm bluefish-debuginfo-2.2.7-1.el6.i686.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/x86_64/bluefish-debuginfo-2.2.7-1.el6.x86_64.rpm bluefish-debuginfo-2.2.7-1.el6.x86_64.rpm]<br />
<br />
= Installing Bluefish on openSUSE =<br />
<br />
Bluefish is available in the main repository. Launch YaST and search for "bluefish" to find and select the appropriate package to install.<br />
<br />
This process is also automated through 1-Click-Install on the openSUSE Build Service: https://software.opensuse.org/package/bluefish<br />
<br />
= Installing Bluefish on AltLinux =<br />
<br />
<br />
= Installing Bluefish on Slackware =<br />
<br />
= Installing Bluefish on Mac OS X =<br />
<br />
Download the latest version installer from http://www.bennewitz.com/bluefish/stable/binaries/macosx/, open it and drag the bluefish icon onto Applications.<br />
<br />
In Mavericks there is a system setting called ''Gatekeeper'' that only allows you to install packages from Apple-identified developers. Bluefish is not distributed through the Apple app store, so you will have to workaround that setting.<br />
<br />
Use the contextual menu (e.g. secondary-click button), and you'll see a menu with "Open" in it.<br />
This will present you with a dialogue box, asking you for permission to run the software.<br />
You will only be asked this the first time.<br />
<br />
Alternatively, the ''Gatekeeper'' setting can be disabled. For information, see: <br />
https://kb.wisc.edu/helpdesk/page.php?id=25443 or http://support.apple.com/kb/ht5290<br />
<br />
= Installing Bluefish on Windows XP or newer =<br />
<br />
=== Installing with internet connection ===<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
The installer will require internet access to download GTK+ and any spell check dictionaries. Please note that the internet-enabled setup may fail if the installer is run from a network share. See below for instructions for internet-less installation.<br />
<br />
==== Installing without Internet Access ====<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
Download the GTK+ 2.24.8 installer (from the gtk-win project): <br />
http://downloads.sourceforge.net/gtk-win/gtk2-runtime-2.24.8-2011-12-03-ash.exe?download<br />
<br />
Download any language dictionaries you wish to be able to install: <br />
http://www.muleslow.net/files/aspell/lang/<br />
<br />
Place the files in a new directory named 'redist' in the same directory as the Bluefish installer.<br />
e.x.<br />
Bluefish\<br />
Bluefish\Bluefish-2.2.7-setup.exe<br />
Bluefish\redist\gtk2-runtime-2.24.8-2011-12-03-ash.exe<br />
Bluefish\redist\aspell6-en-7.1-0.tbz2<br />
<br />
The installer will fall back on downloading the files if they are not found in the redist folder, or if the checksum of the local copy is invalid.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2691Writing language definition files2016-01-15T10:20:23Z<p>OlivierSessink: /* hardcoded option names */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names that can be used in the language file:<br />
<br />
The '_foldable' suffix is hardcoded in bluefish. It should be followed by block_name that is used in the language file somewhere. The attribute block_name can be in an <element> tag. In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. <br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
The 'is_' suffix is hardcoded in bluefish. It should be followed by the language name. This is useful for include files that are included in several different languages. This option is not set by the user, it is always present during compilation.<br />
The following example starts a PHP open tag, but only if the file is being included in the PHP language:<br />
<group class="is_PHP"><element idref="e.php.short.open" /></group><br />
See more about this in the section '''Advanced group class/notclass values'''<br />
<br />
There are also a few global options that are hardcoded:<br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that for example attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. you may use<br />
- a range of characters such as [a-z0-9;']<br />
- an inverted range such as [^0-9]<br />
- operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
- subpatterns such as ab(fg)?<br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. See also the section on hardcoded option names. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2690Writing language definition files2016-01-15T10:19:34Z<p>OlivierSessink: /* groups that can be disabled/enabled with an option */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names that can be used in the language file:<br />
<br />
The '_foldable' suffix is hardcoded in bluefish. It should be followed by block_name that is used in the language file somewhere. The attribute block_name can be in an <element> tag. In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. <br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
The 'is_' suffix is hardcoded in bluefish. It should be followed by the language name. This is useful for include files that are included in several different languages. This option is not set by the user, it is always present during compilation.<br />
The following example starts a PHP open tag, but only if the file is being included in the PHP language:<br />
<group class="is_PHP"><element idref="e.php.short.open" /></group><br />
<br />
There are also a few global options that are hardcoded:<br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that for example attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. you may use<br />
- a range of characters such as [a-z0-9;']<br />
- an inverted range such as [^0-9]<br />
- operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
- subpatterns such as ab(fg)?<br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. See also the section on hardcoded option names. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2689Writing language definition files2016-01-15T10:19:17Z<p>OlivierSessink: /* groups that can be disabled/enabled with an option */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names that can be used in the language file:<br />
<br />
The '_foldable' suffix is hardcoded in bluefish. It should be followed by block_name that is used in the language file somewhere. The attribute block_name can be in an <element> tag. In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. <br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
The 'is_' suffix is hardcoded in bluefish. It should be followed by the language name. This is useful for include files that are included in several different languages. This option is not set by the user, it is always present during compilation.<br />
The following example starts a PHP open tag, but only if the file is being included in the PHP language:<br />
<group class="is_PHP"><element idref="e.php.short.open" /></group><br />
<br />
There are also a few global options that are hardcoded:<br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that for example attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. you may use<br />
- a range of characters such as [a-z0-9;']<br />
- an inverted range such as [^0-9]<br />
- operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
- subpatterns such as ab(fg)?<br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. See also the section on hardcoded option names. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
The hardcoded option 'is_<language name>' can be useful in an include file that is included in multiple languages. See the section on hardcoded option names.<br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2688Writing language definition files2016-01-15T10:17:48Z<p>OlivierSessink: /* Block detection */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names that can be used in the language file:<br />
<br />
The '_foldable' suffix is hardcoded in bluefish. It should be followed by block_name that is used in the language file somewhere. The attribute block_name can be in an <element> tag. In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. <br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
The 'is_' suffix is hardcoded in bluefish. It should be followed by the language name. This is useful for include files that are included in several different languages. This option is not set by the user, it is always present during compilation.<br />
The following example starts a PHP open tag, but only if the file is being included in the PHP language:<br />
<group class="is_PHP"><element idref="e.php.short.open" /></group><br />
<br />
There are also a few global options that are hardcoded:<br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that for example attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. you may use<br />
- a range of characters such as [a-z0-9;']<br />
- an inverted range such as [^0-9]<br />
- operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
- subpatterns such as ab(fg)?<br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. See also the section on hardcoded option names. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2687Writing language definition files2016-01-15T10:16:59Z<p>OlivierSessink: /* hardcoded option names */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names that can be used in the language file:<br />
<br />
The '_foldable' suffix is hardcoded in bluefish. It should be followed by block_name that is used in the language file somewhere. The attribute block_name can be in an <element> tag. In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. <br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
The 'is_' suffix is hardcoded in bluefish. It should be followed by the language name. This is useful for include files that are included in several different languages. This option is not set by the user, it is always present during compilation.<br />
The following example starts a PHP open tag, but only if the file is being included in the PHP language:<br />
<group class="is_PHP"><element idref="e.php.short.open" /></group><br />
<br />
There are also a few global options that are hardcoded:<br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that for example attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. you may use<br />
- a range of characters such as [a-z0-9;']<br />
- an inverted range such as [^0-9]<br />
- operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
- subpatterns such as ab(fg)?<br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2661Writing language definition files2015-06-05T08:09:30Z<p>OlivierSessink: /* The auto_re_use_attributes tag in the properties section */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names:<br />
<br />
In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. The '_foldable' suffix is hardcoded in bluefish.<br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that for example attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. you may use<br />
- a range of characters such as [a-z0-9;']<br />
- an inverted range such as [^0-9]<br />
- operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
- subpatterns such as ab(fg)?<br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2660Writing language definition files2015-06-05T08:08:53Z<p>OlivierSessink: /* The properties section */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names:<br />
<br />
In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. The '_foldable' suffix is hardcoded in bluefish.<br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
== The auto_re_use_attributes tag in the properties section ==<br />
Added in 2.2.8: some or most markup languages keep the definition of an attribute constant over the complete language. Meaning that attribute "color" has the same meaning and the same acceptable values, no matter in which tag it is used.<br />
<br />
For those languages it is recommended to set :<br />
<pre><br />
<auto_re_use_attributes enabled="1" /><br />
</pre><br />
this will make bluefish re-use existing attribute pattern where possible. In HTML (for example) this saves 4000 patterns that are not needed because re-use is possible.<br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. you may use<br />
- a range of characters such as [a-z0-9;']<br />
- an inverted range such as [^0-9]<br />
- operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
- subpatterns such as ab(fg)?<br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2657Writing language definition files2015-05-17T20:11:51Z<p>OlivierSessink: /* The smartindent and smartoutdent tags in the properties section */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names:<br />
<br />
In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. The '_foldable' suffix is hardcoded in bluefish.<br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{([" /><br />
<smartoutdent characters="})]" /><br />
</pre><br />
Currently the smart indenting only looks for the last character, it will not work on words (anything with multiple characters).<br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. you may use<br />
- a range of characters such as [a-z0-9;']<br />
- an inverted range such as [^0-9]<br />
- operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
- subpatterns such as ab(fg)?<br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Debugging_Bluefish&diff=2655Debugging Bluefish2015-04-23T07:10:05Z<p>OlivierSessink: </p>
<hr />
<div>__TOC__<br />
<br />
= Providing information =<br />
<br />
In general: It is always a good idea to tell us your version of Bluefish and your version of '''GTK/Glib installed''' on your system, both can be found in the '''About''' menu. Also don't forget to mention the platform (Linux, OSX, Windows, FreeBSD, etc.) and it's version. If you have the possibility to test it on multiple computers with different platforms or versions this will really help to track down the problem. If you can reproduce a crash on some specific file, please send us the file too. The smaller the file, the easier for us to debug the issue.<br />
<br />
Crash reports / bugs are collected here: https://bugzilla.gnome.org/page.cgi?id=browse.html&product=bluefish<br />
<br />
= Specific crash information =<br />
<br />
== Debugging symbols ==<br />
<br />
To create a meaningful backtrace you'll need a binary with the debugging symbols attached. Otherwise your backtrace will contain a lot of question marks and won't be useful.<br />
<br />
=== Compile with debugging symbols from source ===<br />
<br />
[http://bfwiki.tellefsen.net/index.php/Getting_Bluefish#Downloading_the_source Get the source]. To compile it with debugging symbols, CFLAGS must contain '''-g'''. You should also use the '''-O0''' optimization flag there.<br /><br />
<tt>$ ./configure CFLAGS="-g -O0" && make</tt><br />
<br />
For more information about compiling from source, see [[Compiling Bluefish from source]].<br />
<br />
The stable version of bluefish, namely 2.2.X at the time of writing, currently strips the debugging symbols during the installation step ('''make install'''). In this case only re-compile the sources and run the resulting binary '''src/bluefish''' in the GNU Debugger.<br />
<br />
=== Install debugging symbols on Debian/Ubuntu systems ===<br />
<br />
For Debian and Ubuntu there are packages available with debugging symbols. This package is called bluefish-dbg. Just install it the usual way, for example from the commandline with "apt-get install bluefish-dbg"<br />
<br />
You might need some more packages of this type: '''libc6-dbg''', '''libglib2.0-0-dbg''', '''libgtk-3-0-dbg''', '''libpcre3-dbg''', '''libxml2-dbg'''.<br />
<br />
== Run Bluefish in the debugger ==<br />
<br />
=== Create a meaningful backtrace ===<br />
<br />
To run Bluefish in the GNU Debugger, use:<br />
<br />
gdb bluefish<br />
<br />
or for the '''1.0 series''' (see above):<br />
<br />
gdb src/bluefish<br />
<br />
Then ('''(gdb)''' represents the gdb shell prompt!):<br />
<br />
(gdb) set logging on<br />
Copying output to gdb.txt.<br />
(gdb) r<br />
<br />
This will start bluefish. Now reproduce the crash and then create the backtrace:<br />
<br />
Program received signal SIGSEGV, Segmentation fault.<br />
...<br />
(gdb) bt full<br />
...<br />
(gdb) quit<br />
<br />
Now you'll find a file '''gdb.txt''' in the directory. [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Open a report in our BTS] and attach this file to the report. This is what a [[Backtrace Should Look Like]].<br />
<br />
=== Debugging a Gtk-Critical error ===<br />
<br />
If you set the environment variable '''G_DEBUG''' to ''fatal_warnings'', e.g.<br />
<br />
export G_DEBUG=fatal_warnings<br />
<br />
with bash, it should assert when there is an error. Then launch bluefish with gdb as told you above and you can get a backtrace.<br />
<br />
== Notes and references ==<br />
<br />
References: <references/></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Debugging_Bluefish&diff=2654Debugging Bluefish2015-04-23T07:09:08Z<p>OlivierSessink: </p>
<hr />
<div>__TOC__<br />
<br />
= Providing information =<br />
<br />
In general: It is always a good idea to tell us your version of Bluefish and your version of '''GTK/Glib installed''' on your system, both can be found in the '''About''' menu. Also don't forget to mention the platform (Linux, OSX, Windows, FreeBSD, etc.) and it's version. If you have the possibility to test it on multiple computers with different platforms or versions this will really help to track down the problem. If you can reproduce a crash on some specific file, please send us the file too. The smaller the file, the easier for us to debug the issue.<br />
<br />
Crash reports / bugs are collected here: https://bugzilla.gnome.org/page.cgi?id=browse.html&product=bluefish<br />
<br />
= Specific crash information =<br />
<br />
== Debugging symbols ==<br />
<br />
To create a meaningful backtrace you'll need a binary with the debugging symbols attached. Otherwise your backtrace will contain a lot of question marks and won't be useful.<br />
<br />
=== Compile with debugging symbols from source ===<br />
<br />
[http://bfwiki.tellefsen.net/index.php/Getting_Bluefish#Downloading_the_source Get the source]. To compile it with debugging symbols, CFLAGS must contain '''-g'''. You should also use the '''-O0''' optimization flag there.<br /><br />
<tt>$ ./configure CFLAGS="-g -O0" && make</tt><br />
<br />
For more information about compiling from source, see [[Compiling Bluefish from source]].<br />
<br />
The stable version of bluefish, namely 2.2.X at the time of writing, currently strips the debugging symbols during the installation step ('''make install'''). In this case only re-compile the sources and run the resulting binary '''src/bluefish''' in the GNU Debugger.<br />
<br />
=== Install debugging symbols on Debian/Ubuntu systems ===<br />
<br />
For Debian and Ubuntu there are packages available with debugging symbols. This package is called bluefish-dbg. Just install it the usual way, for example from the commandline with "apt-get install bluefish-dbg"<br />
<br />
You might need some more packages of this type: '''libc6-dbg''', '''libglib2.0-0-dbg''', '''libgtk-3-0-dbg''', '''libpcre3-dbg''', '''libxml2-dbg'''.<br />
<br />
== Run Bluefish in the debugger ==<br />
<br />
=== Create a meaningful backtrace ===<br />
<br />
To run Bluefish in the GNU Debugger, use:<br />
<br />
gdb bluefish<br />
<br />
or for the '''1.0 series''' (see above):<br />
<br />
gdb src/bluefish<br />
<br />
Then ('''(gdb)''' represents the gdb shell prompt!):<br />
<br />
(gdb) set logging on<br />
Copying output to gdb.txt.<br />
(gdb) r<br />
<br />
This will start bluefish. Now reproduce the crash and then create the backtrace:<br />
<br />
Program received signal SIGSEGV, Segmentation fault.<br />
...<br />
(gdb) bt full<br />
...<br />
(gdb) quit<br />
<br />
Now you'll find a file '''gdb.txt''' in the directory. [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Open a report in our BTS] and attach this file to the report. This is what a [[Backtrace Should Look Like]].<br />
<br />
=== What other information you should provide to the developers ===<br />
<br />
* the platform you are using<br />
* the gtk version you are using<br />
* the compiler version you are using<br />
* any non-default ./configure options<br />
* the pcre version you are using if you think that is related<br />
* the libaspell version you are using if you think that is related<br />
* the gnome-vfs version you are using if you think that is related (only 1.0 series)<br />
<br />
=== Debugging a Gtk-Critical error ===<br />
<br />
If you set the environment variable '''G_DEBUG''' to ''fatal_warnings'', e.g.<br />
<br />
export G_DEBUG=fatal_warnings<br />
<br />
with bash, it should assert when there is an error. Then launch bluefish with gdb as told you above and you can get a backtrace.<br />
<br />
== Notes and references ==<br />
<br />
References: <references/></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Debugging_Bluefish&diff=2653Debugging Bluefish2015-04-13T18:46:09Z<p>OlivierSessink: /* Install debugging symbols on Debian/Ubuntu systems */</p>
<hr />
<div>__TOC__<br />
<br />
<br />
In general: It is always a good idea to tell us your version of '''GTK/Glib installed''' on your system.<br />
<br />
== Debugging symbols ==<br />
<br />
To create a meaningful backtrace you'll need a binary with the debugging symbols attached. Otherwise your backtrace will contain a lot of question marks and won't be useful.<br />
<br />
=== Compile with debugging symbols from source ===<br />
<br />
[http://bfwiki.tellefsen.net/index.php/Getting_Bluefish#Downloading_the_source Get the source]. To compile it with debugging symbols, CFLAGS must contain '''-g'''. You should also use the '''-O0''' optimization flag there.<br /><br />
<tt>$ ./configure CFLAGS="-g -O0" && make</tt><br />
<br />
For more information about compiling from source, see [[Compiling Bluefish from source]].<br />
<br />
The stable version of bluefish, namely 2.2.X at the time of writing, currently strips the debugging symbols during the installation step ('''make install'''). In this case only re-compile the sources and run the resulting binary '''src/bluefish''' in the GNU Debugger.<br />
<br />
=== Install debugging symbols on Debian/Ubuntu systems ===<br />
<br />
For Debian and Ubuntu there are packages available with debugging symbols. This package is called bluefish-dbg. Just install it the usual way, for example from the commandline with "apt-get install bluefish-dbg"<br />
<br />
You might need some more packages of this type: '''libc6-dbg''', '''libglib2.0-0-dbg''', '''libgtk-3-0-dbg''', '''libpcre3-dbg''', '''libxml2-dbg'''.<br />
<br />
== Run Bluefish in the debugger ==<br />
<br />
=== Create a meaningful backtrace ===<br />
<br />
To run Bluefish in the GNU Debugger, use:<br />
<br />
gdb bluefish<br />
<br />
or for the '''1.0 series''' (see above):<br />
<br />
gdb src/bluefish<br />
<br />
Then ('''(gdb)''' represents the gdb shell prompt!):<br />
<br />
(gdb) set logging on<br />
Copying output to gdb.txt.<br />
(gdb) r<br />
<br />
This will start bluefish. Now reproduce the crash and then create the backtrace:<br />
<br />
Program received signal SIGSEGV, Segmentation fault.<br />
...<br />
(gdb) bt full<br />
...<br />
(gdb) quit<br />
<br />
Now you'll find a file '''gdb.txt''' in the directory. [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Open a report in our BTS] and attach this file to the report. This is what a [[Backtrace Should Look Like]].<br />
<br />
=== What other information you should provide to the developers ===<br />
<br />
* the platform you are using<br />
* the gtk version you are using<br />
* the compiler version you are using<br />
* any non-default ./configure options<br />
* the pcre version you are using if you think that is related<br />
* the libaspell version you are using if you think that is related<br />
* the gnome-vfs version you are using if you think that is related (only 1.0 series)<br />
<br />
=== Debugging a Gtk-Critical error ===<br />
<br />
If you set the environment variable '''G_DEBUG''' to ''fatal_warnings'', e.g.<br />
<br />
export G_DEBUG=fatal_warnings<br />
<br />
with bash, it should assert when there is an error. Then launch bluefish with gdb as told you above and you can get a backtrace.<br />
<br />
== Notes and references ==<br />
<br />
References: <references/></div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Installing_Bluefish&diff=2652Installing Bluefish2015-03-03T21:31:14Z<p>OlivierSessink: /* Installing Bluefish on Mac OS X */</p>
<hr />
<div>= Installing Bluefish on Debian GNU/Linux =<br />
<br />
== Installing the release that is part of Debian / Ubuntu / Mint / etc. ==<br />
<br />
Use<br />
<br />
sudo apt-get install bluefish<br />
sudo aptitude install bluefish<br />
<br />
or any other frontend for the package manager such as synaptic or simply "add / remove programs".<br />
<br />
== Installing the very latest release on Debian ==<br />
<br />
=== Installing the very latest release on Debian 7.0 (Wheezy/Stable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/stable-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian wheezy-backports main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian stable-backports main<br />
<br />
And install the package via:<br />
<br />
apt-get -t wheezy-backports install bluefish<br />
<br />
Report any bugs to the Debian bugtracker.<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
=== Installing the very latest release on Debian 6.0 (Squeeze/Oldstable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/stable-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports squeeze-backports-sloppy main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports oldstable-backports-sloppy main<br />
<br />
And install the package via:<br />
<br />
apt-get -t squeeze-backports-sloppy install bluefish<br />
<br />
This version is built with the GTK+ 2 libraries. Report any bugs to the Debian bugtracker.<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
== Installing the very latest on Ubuntu Linux ==<br />
<br />
You'll find recent packages of '''bluefish''' in [https://launchpad.net/~klaus-vormweg/+archive/bluefish the Bluefish PPA maintained by Klaus Vormweg]. Follow the instructions given there to add this repository. Then '''bluefish''' can be updated to its latest release:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
=== Removing obsolete debian.wgdd.de entries from sources.list ===<br />
<br />
The http://debian.wgdd.de/ repository no longer provides packages of bluefish. The above steps make the following entries to either ''/etc/apt/sources.list'' or ''/etc/apt/sources.list.d/debian.wgdd.de_*.list'' or any other file in ''/etc/apt/sources.list.d/'' obsolete. You can safely remove any references to the http://debian.wgdd.de repository, that may look like these:<br />
<br />
deb http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb-src http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb http://debian.wgdd.de/debian stable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian stable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb-src http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb http://debian.wgdd.de/debian oldstable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian oldstable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
deb-src http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
<br />
and update your system:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Also the '''wgdd-archive-keyring''' package then is obsolete together with the repository keyring. If you have the package installed, do:<br />
<br />
sudo apt-get autoremove --purge wgdd-archive-keyring<br />
<br />
... or if you only had the key:<br />
<br />
sudo apt-key del E394D996<br />
<br />
= Installing Bluefish on Fedora Linux =<br />
<br />
=== Installing the version distributed by Fedora ===<br />
<br />
yum install bluefish<br />
<br />
=== Installing the very latest on Fedora with yum ===<br />
<br />
To enable a bluefish-release yum repository download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-release.repo bluefish-release.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19, 20 and 21. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br/><br />
<br />
=== Installing development versions on Fedora with yum ===<br />
<br />
While care is taken to keep development versions very stable and usable, development versions may crash, contain data eating bugs and incomplete features.<br/><br />
Please report any bugs you might find in [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Bluefish bugzilla]<br/><br />
<br />
If you wish to test the bleeding edge versions of Bluefish currently under development download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-svn.repo bluefish-svn.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19, 20 and 21. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br />
<br />
=== Browsable Yum repo's for Fedora ===<br />
<br />
These pages were created using repoview.<br />
<br />
Fedora 19 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/x86_64/repoview/ x86_64]<br />
<br />
Fedora 20 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/x86_64/repoview/ x86_64]<br />
<br />
Fedora 21 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/21/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/21/x86_64/repoview/ x86_64]<br />
<br />
= Installing Bluefish on RHEL/CentOS 6.5 =<br />
<br />
=== Installing the very latest on RHEL/CentOS 6.5 ===<br />
<br />
Bluefish packages for RHEL/CentOS 6.5 are available at the links below for i386 and x86_64.<br/><br />
These packages require version 6.5. Previous versions prior to 6.5 had GTK+ 2.18.x.<br/><br />
RHEL/CentOS 6.5 has GTK+ 2.20.x which is the minimum version required to build current versions of Bluefish.<br />
<br />
All packages are built using mock. All packages are signed with this gpg [http://bluefish.linuxexperience.net/downloads/fedora/RPM-GPG-KEY-bluefish-svn.asc key].<br />
<br />
<br />
Required for RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-2.2.7-1.el6.i686.rpm bluefish-2.2.7-1.el6.i686.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-shared-data-2.2.7-1.el6.noarch.rpm bluefish-shared-data-2.2.7-1.el6.noarch.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-2.2.7-1.el6.x86_64.rpm bluefish-2.2.7-1.el6.x86_64.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-shared-data-2.2.7-1.el6.noarch.rpm bluefish-shared-data-2.2.7-1.el6.noarch.rpm]<br />
<br />
Optional debug info RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/i386/bluefish-debuginfo-2.2.7-1.el6.i686.rpm bluefish-debuginfo-2.2.7-1.el6.i686.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/x86_64/bluefish-debuginfo-2.2.7-1.el6.x86_64.rpm bluefish-debuginfo-2.2.7-1.el6.x86_64.rpm]<br />
<br />
= Installing Bluefish on openSUSE =<br />
<br />
Bluefish is available in the main repository. Launch YaST and search for "bluefish" to find and select the appropriate package to install.<br />
<br />
This process is also automated through 1-Click-Install on the openSUSE Build Service: https://software.opensuse.org/package/bluefish<br />
<br />
= Installing Bluefish on AltLinux =<br />
<br />
<br />
= Installing Bluefish on Slackware =<br />
<br />
= Installing Bluefish on Mac OS X =<br />
<br />
Download the latest version installer from http://www.bennewitz.com/bluefish/stable/binaries/macosx/, open it and drag the bluefish icon onto Applications.<br />
<br />
In Mavericks there is a system setting called ''Gatekeeper'' that only allows you to install packages from Apple-identified developers. Bluefish is not distributed through the Apple app store, so you will have to workaround that setting.<br />
<br />
Use the contextual menu (e.g. secondary-click button), and you'll see a menu with "Open" in it.<br />
This will present you with a dialogue box, asking you for permission to run the software.<br />
You will only be asked this the first time.<br />
<br />
Alternatively, the ''Gatekeeper'' setting can be disabled. For information, see: <br />
https://kb.wisc.edu/helpdesk/page.php?id=25443 or http://support.apple.com/kb/ht5290<br />
<br />
= Installing Bluefish on Windows XP or newer =<br />
<br />
=== Installing 2.2.7 ===<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
The installer will require internet access to download GTK+ and any spell check dictionaries. Please note that the internet-enabled setup may fail if the installer is run from a network share. See below for instructions for internet-less installation.<br />
<br />
==== Installing without Internet Access ====<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
Download the GTK+ 2.24.8 installer (from the gtk-win project): <br />
http://downloads.sourceforge.net/gtk-win/gtk2-runtime-2.24.8-2011-12-03-ash.exe?download<br />
<br />
Download any language dictionaries you wish to be able to install: <br />
http://www.muleslow.net/files/aspell/lang/<br />
<br />
Place the files in a new directory named 'redist' in the same directory as the Bluefish installer.<br />
e.x.<br />
Bluefish\<br />
Bluefish\Bluefish-2.2.7-setup.exe<br />
Bluefish\redist\gtk2-runtime-2.24.8-2011-12-03-ash.exe<br />
Bluefish\redist\aspell6-en-7.1-0.tbz2<br />
<br />
The installer will fall back on downloading the files if they are not found in the redist folder, or if the checksum of the local copy is invalid.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2650Writing language definition files2015-02-17T21:29:17Z<p>OlivierSessink: /* Advanced option: identifier autocompletion */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names:<br />
<br />
In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. The '_foldable' suffix is hardcoded in bluefish.<br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{" /><br />
<smartoutdent characters="}" /><br />
</pre><br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. you may use<br />
- a range of characters such as [a-z0-9;']<br />
- an inverted range such as [^0-9]<br />
- operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
- subpatterns such as ab(fg)?<br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup, or they can be used in the jump function .<br />
<br />
* identifier_mode = 1: the match itself will be autocompleted<br />
* identifier_mode = 2: the identifier that follows this match will be autocompleted<br />
<br />
This example is from the php language file, this will make a php variable show up in the autocompletion popup:<br />
<element pattern="$[a-zA-Z_][a-zA-Z0-9_]*" is_regex="1" case_insens="1" highlight="php-variable" identifier_mode="2" identifier_autocomp="1"/><br />
<br />
This example is from the php language file, this will make a php function show up in the autocompletion popup, and you can jump to the definition of the function anywhere in the code where the function is used:<br />
<element pattern="function" identifier_mode="1" identifier_jump="1" identifier_autocomp="1" /><br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Writing_language_definition_files&diff=2649Writing language definition files2015-02-17T20:35:18Z<p>OlivierSessink: /* The definition section */</p>
<hr />
<div>= Bluefish language definition files =<br />
<br />
All syntax highlighting and autocompletion is defined in bluefish language definition files, saved in .bflang2 files. In the source code they can be found in data/bflang/<br />
<br />
== Linux Language file location ==<br />
<br />
On Linux they are installed in /usr/share/bluefish/bflang/ or /usr/local/share/bluefish/bflang/ if you compiled Bluefish from source.<br />
<br />
== Mac OSX Language file location ==<br />
<br />
Go to Applications. Right click on Bluefish and select Show Package Contents. Then navigate Contents->Resources->share->bluefish->bflang <br />
<br />
== Example files ==<br />
shell.bflang2 is the most simple example of what a language definition can look like. php.bflang2 is probably the most complex example with many included files and many different syntax types supported within another syntax (javascript, css, html and php itself). There is also sample.bflang2 that describes more or less the same as this wikipage.<br />
<br />
== Editing bflang files ==<br />
If you store a bflang2 file in your bluefish settings directory ~/.bluefish/ it has higher priority than the system wide installed files. So if you are going to change a bflang2 file, just copy it (and any files it includes) into ~/.bluefish/<br />
<br />
If you start bluefish from the commandline it will output errors and warnings about the bflang2 files that are loaded. So after you have edited a bflang2 file, test it, and look at the output in the terminal.<br />
<br />
== Including files ==<br />
<br />
The top of a bflang file may define new entities that will include another file.<br />
For example the line<br />
<pre><!ENTITY css-rules SYSTEM "css-rules.bfinc"></pre><br />
defines that &amp;css-rules; should be replaced by the contents of css-rules.bfinc (which should be placed in the same directory)<br />
<br />
This makes it easier to re-use syntax. CSS is for example used in html, php and css itself.<br />
<br />
= The format of the file =<br />
<br />
The file format is XML.<br />
<br />
It starts with a root tag <bflang>:<br />
<br />
<pre><br />
<bflang name="Shell" version="2.0" ><br />
</bflang><br />
</pre><br />
<br />
Inside the root tag there are three sections<br />
<br />
= The header section =<br />
The header section is always loaded for each bflang2 file. The rest of the file is loaded "on demand", so only if it is needed.<br />
<br />
<pre><br />
<header><br />
<mime type="application/x-shellscript"/><br />
<option name="show_in_menu" default="1"/><br />
<highlight name="value" style="value" /><br />
</header><br />
</pre><br />
<br />
== The mime tag in the header ==<br />
<br />
The mime tag specifies for which mime types this definition file is used. There can be multiple mime types specified. Sometimes a file doesn't have a specific mime type, or the mime type is not defined<br />
on many systems. In that case the mime type is often something like text/plain<br />
Bluefish supports a combination of mime type and extension. To detect a file type that<br />
ends on .fake you add<br />
<pre><br />
<mime type="application/x-fake"/><br />
<mime type="text/plain?fake"/><br />
</pre><br />
<br />
== The option tag in the header ==<br />
The option tag defines an option that is used further on in the language file<br />
<pre><br />
<option name="allphpfunctions" default="1" description="All php functions" /><br />
</pre><br />
<br />
'''''A special note:''' All language files share one list of option names and their description. So if two or more options have the same name, they will get the same description in Bluefish. If they have a different description inside the file, it is not defined which description is used!!!''<br />
<br />
An option is a boolean value that is referred to in ''class'' and ''notclass'' attributes.<br />
<br />
Adding<br />
<pre>class="allphpfunctions"</pre><br />
means the tag is enabled if the user option is enabled.<br />
<br />
Adding<br />
<pre>notclass="allphpfunctions"</pre><br />
means the tag is disabled if the user option is enabled.<br />
<br />
These attributes exist for <element />, <tag />, <group /> and <autocomplete /> <br />
<br />
==== hardcoded option names ====<br />
<br />
There are a few special (hardcoded) option names:<br />
<br />
In the next example a block named 'php block' is made optionally foldable (or not). Read more about block detection in the <element /> section. The '_foldable' suffix is hardcoded in bluefish.<br />
<pre><option name="php block_foldable" default="1" description="Allow the PHP block to fold"/></pre><br />
<br />
Whether or not to load the reference data for this language (saves memory)<br />
<pre><option name="load_reference" default="1"/></pre><br />
<br />
Whether or not to load the auto completion data for this language (saves memory)<br />
<pre><option name="load_completion" default="1" /></pre><br />
<br />
Whether or not to close <tag> in the auto-completion<br />
<option name="autocomplete_tags" default="1" /><br />
<br />
Whether or not to show this language by default in the menu<br />
<pre><option name="show_in_menu" default="0"/></pre><br />
<br />
==== Referring to an option further on in the language file, in tag or element ====<br />
<br />
Since 2.2.5 Bluefish supports boolean variables inside the language file (that thus have value 0 or 1). There are two ways these can be used, as option: (for boolean values) and as condition: (for string values).<br />
<pre><br />
<element pattern="foo" highlight="condition:foo_as_string?string:function" ><br />
<autocomplete enable="option:autocomplete_foo" /><br />
</element><br />
</pre><br />
<br />
== The highlight tag in the header ==<br />
<br />
The higlight tag defines which element-types that are defined in<br />
the file, and which styles should be applied for each of these types. THESE CAN BE ALTERED<br />
BY THE USER IN THE PREFERENCES PANEL..<br />
<br />
So if an element in this file has attribute highlight="foo", this section should have<br />
<highlight name="foo" style="somestyle"/>. Look at other language files and try to<br />
re-use styles !!!!!!!!!<br />
<br />
For the end-user it is convenient if styles are re-used. All languages that define a comment<br />
should use style 'comment' by default.<br />
<br />
<pre><highlight name="comment" style="comment" /></pre><br />
<br />
Some users may like the same color for all keywords, other may like a different style for<br />
storage types and language keywords. So use a different 'highlight' name for them, such that<br />
users may assign a different textstyle if they want.<br />
<pre><highlight name="storage-types" style="keyword" /><br />
<highlight name="keyword" style="keyword" /></pre><br />
<br />
= The properties section =<br />
<br />
The properties section is similar to the header, but it is loaded on-demand. As long as there is no syntax scanning needed for this type of file, the properties section is not yet loaded. <br />
<br />
== The comment tag in the properties section ==<br />
the comment tag defines which type of line comments and block comments that could exist in this language. The smart comment function shift-ctrl-c uses this information to comment or uncomment<br />
<pre><br />
<comment id="cm.cblockcomment" type="block" start="/*" end="*/" /><br />
<comment id="cm.htmlcomment" type="block" start="&lt;!--" end="--&gt;" /><br />
<comment id="cm.cpplinecomment" type="line" start="//" /><br />
<comment id="cm.scriptcomment" type="line" start="#" /><br />
</pre><br />
== The smartindent and smartoutdent tags in the properties section ==<br />
smartindent characters specify which characters, followed by a return, should increase the indenting. Smartoutdent means that this character, typed immediately after auto-indenting has set the indenting, should<br />
decrease the previous auto-indenting<br />
<pre><br />
<smartindent characters="{" /><br />
<smartoutdent characters="}" /><br />
</pre><br />
<br />
== The default_spellcheck tag in the properties section ==<br />
default_spellcheck defines if regions that are not highlighted will be checked by the spell checker. This is typically enabled for markup languages like HTML and XML, and disabled (or left out, because the default=0) for all programming languages<br />
<pre><br />
<default_spellcheck enabled="1" /><br />
</pre><br />
<br />
= The definition section =<br />
The definition section is where the syntax is really described. <br />
<br />
A language definition always<br />
starts with a <context> tag, and contains ONE SINGLE context tag (which may have other context tags<br />
as children).<br />
<br />
==== The concept of contexts ====<br />
<br />
Different positions in a file may have a different syntax. An HTML example: inside a comment you can have a < character without breaking the syntax. That means that the syntax scanner inside a HTML comment is only looking for the end of the comment. But outside the comment it is looking for tags, or entities. Thus the syntax scanner runs in two different contexts: the main context (where a tag, entity or comment may be started), and the comment context (where only the end of the comment is relevant). But inside a tag we have again a new context, because we only look for attributes. And we may have CSS inside HTML, or javascript. And inside javascript we can again have a comment. Etc. etc. etc. The HTML syntax currently has 465 contexts. <br />
<br />
The syntax scanner always is in '''one single context'''.<br />
<br />
== The context tag in the definition section ==<br />
<br />
<pre><context symbols="&amp;gt;&amp;lt;&amp;amp;; &amp;#9;&amp;#10;&amp;#13;" commentid_block="cm.htmlcomment" commentid_line="none"></pre><br />
Or<br />
<pre><context symbols="LIST OF CHARACTERS" highlight="HIGHLIGHT-TYPE" id="IDENTIFIER" > </pre><br />
<br />
A <context> tag should always define '''symbols'''. Symbols are those characters that may start or end an element.<br />
<br />
The optional attribute '''highlight''' may specify a highlight type that is valid for the complete text region<br />
that has this context. Useful for 'comment' or 'string' type of contexts where the complete context is<br />
highlighted<br />
<br />
The optional attributes '''commentid_block''' and '''commentid_line''' may specify how the comment toggle function should work in this context. The value should refer to the comment section in the properties.<br />
<br />
==== What are symbols ====<br />
Symbols are characters that may start or end a pattern.<br />
Try to highlight for example:<br />
<pre><br />
char *rc_char(char*chara);<br />
^^^^ ^^^^<br />
</pre><br />
Only two of the four 'char' need to be highlighted. How does the scanner know which<br />
one to highlight? In the above example there are several symbols such as whitespace<br />
, brackets and operators:<br />
<pre><br />
char *rc_char(char*chara);<br />
^ ^^ ^ ^ ^^<br />
</pre><br />
see that the occurences of 'char' that should be highlighted are all in between symbols?!<br />
<br />
To detect function strlen in the following examples (language C):<br />
<pre>i=strlen(a);<br />
i+strlen(a);<br />
i*strlen (a);</pre><br />
we need at least symbols ''=+*(''<br />
<br />
In most languages all whitespace is a symbol ( =space, &amp;#9;=tab, &amp;#10;=newline, &amp;#13;=carriange return).<br />
<br />
In xml/sgml/html only '<>&amp;;' are symbols, but withtin a tag also " and ' are symbols.<br />
<br />
==== Advanced use of context tags ====<br />
The optional attribute '''id''' is used to define an identifier which can be used to re-use this context. To re-use a context, use <br />
<pre><context idref="IDENTIFIER" /></pre><br />
where IDENTIFIER refers to a previously defined context with an id. The file is parsed top to bottom, so previous must be earlier in the file.<br />
<br />
<br />
=== Inside a context tag ===<br />
<br />
Inside a context tag are usually the tags element, tag, group. For advanced usage it can have another context.<br />
<br />
==== Advanced use of context tags ====<br />
''If there is a context inside another context, it must have it's id set.'' This context is defined but not yet used. It can be used if it is referred to with <context idref="" /><br />
<br />
== The element tag in the definition section ==<br />
<br />
<pre><element pattern="while" highlight="keyword"/></pre><br />
<br />
<element> defines an element that is highlighted, or can be autocompleted, or an element that starts a new context<br />
<br />
it always needs attribute 'pattern' which defines the pattern that will be looked for in this context<br />
<br />
the pattern can be defined in 'regular expression' style, to do this add attribute is_regex="1". however, there is<br />
only limited regular expression support. you may use<br />
- a range of characters such as [a-z0-9;']<br />
- an inverted range such as [^0-9]<br />
- operators such as ? (zero or one), + (one or more), and * (zero or more)<br />
- subpatterns such as ab(fg)?<br />
<br />
<pre><element pattern="'[^']*'" is_regex="1" highlight="string"/></pre><br />
<br />
a pattern may be case insensitive, set case_insens="1"<br />
<br />
to highlight the pattern use attribute highlight="TYPE", where TYPE should be defined within the <header><br />
section of the language file<br />
==== Element re-use ====<br />
<element> may have attribute 'id' so this element may be referred to later. To re-use element 'foo' later in the file use <br />
<pre><element idref="foo" /></pre><br />
<br />
==== Block detection ====<br />
Next is a block detection example<br />
<pre><element id="bracket{" pattern="{" starts_block="1" highlight="brackets" block_name="Bracket block" /><br />
<element pattern="}" ends_block="1" blockstartelement="bracket{" highlight="brackets" /></pre><br />
an element may start or end a block. a block consists of two patterns (start and end) where the contents between<br />
the start and the end may be hidden when the block is 'folded'.<br />
<br />
to make a pattern a block start define starts_block="1" and use the 'id' attribute<br />
<br />
to specify a pattern that ends a block use ends_block="1" and use blockstartelement="FOO" where FOO is the id of<br />
the start-of-block-element<br />
<br />
Because this block has a name ('Bracket block') it can be selected by the user in the<br />
expand/collapse popup menu. You can also create an option 'Bracket block_foldable' in the header options so<br />
the user may decide if this block may fold or not. If you don't need either the<br />
block_name can be left empty.<br />
<br />
==== An element may start a new context ====<br />
Next is an context example, a javascript comment<br />
<pre><element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
</context><br />
</element></pre><br />
whenever this pattern is found the engine switches to this context<br />
and starts scanning only the patterns defined in this context. To do this define <context></context><br />
between <element> and </element>. within this <context> there are entirely different patterns. There<br />
can be only 1 context within an element.<br />
<br />
There is an end of the context too in most languages. To make the scanner switch back to the previous context<br />
an element INSIDE the inner context that has ends_context="NUM" where NUM specifies the number of contexts<br />
that are ended by this element. Because<br />
context may be nested there may be several contexts inside each other.<br />
<br />
Basically context switches work like a stack. Lets take the example<br />
<pre><br />
i = 1;<br />
/* text */<br />
i = 1 + 1;<br />
</pre><br />
pattern '/*' exists in the initial context, but when it is found, the initial context is pushed on the<br />
context stack, and the scanner switches to a new context context (for c-style-comment). In this context<br />
there exists only a single pattern: '*/'<br />
The scanner now continues until it finds */, at this point it pops 1 context from the stack, and thus in<br />
this example it continues with the initial context<br />
<br />
Next is a nested context example, inside a php comment, there may be the end of the php block. Note that<br />
this element has ends_context=2<br />
<pre><br />
<element pattern="&lt;?php" highlight="php-block"><br />
<context symbols="?*/+-=*&amp;amp;&amp;lt;&amp;gt;&amp;#9;&amp;#10;&amp;#13;"><br />
<element pattern="?&gt;" highlight="php-block" ends_context="1" /><br />
<element pattern="/*" highlight="c-style-comment"><br />
<context symbols="*/&amp;#9;&amp;#10;&amp;#13;" highlight="c-style-comment"><br />
<element pattern="*/" highlight="c-style-comment" ends_context="1" /><br />
<element pattern="?&gt;" highlight="php-block" ends_context="2" /><br />
</context><br />
</element><br />
</context><br />
</element><br />
</pre><br />
<br />
==== Auto completion ====<br />
<br />
an pattern may also be autocompletable. to enable this add <br />
<pre><autocomplete enable="1" /></pre><br />
<br />
Often it is convenient if not only the pattern itself can be completed but some common<br />
characters are appended. use append="STRING" to define any characters that<br />
will be autocompleted. The cursor position AFTER auto completion can be set back a couple<br />
of characters. This is defined by attribute backup_cursor.<br />
<br />
<pre><autocomplete append="() {" backup_cursor="3" /></pre><br />
<br />
A regular expession pattern may be autocompletable as well. but to autocomplete the pattern<br />
itself usually makes no sense because it matches various other patterns. use<br />
string="STRING" to autocomplete STRING in this context<br />
<br />
<pre><autocomplete string="import" /></pre><br />
<br />
==== Making auto completion more user configurable ====<br />
<br />
Suppose you want to make auto-completion with or without semicolon configurable. Just add two <autocomplete /> entries, one with a class="" and the other with a notclass="" Then define an option in the header that can be enabled or disabled by the user.<br />
<br />
<pre><element pattern="abort"><reference>Aborting a Program</reference><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
</element></pre><br />
<br />
== The tag tag in the definition section ==<br />
<br />
next example shows a xml/sgml tag with attributes<br />
<pre><tag name="body" highlight="tag" attributes="style,class,id" attribhighlight="attribute" /></pre><br />
because there are many languages that use sgml/xml/html style patterns there is <tag> for convenience.<br />
<br />
it should have attribute 'name' to specify the name of the tag<br />
<br />
the attribute 'attributes' defines attributes that are valid for this tag<br />
<br />
to highlight the tag use highlight="TYPE" where TYPE is the highlight type defined in the <header> section<br />
to highlight attributes use attrib_highlight="TYPE"<br />
<br />
next example show the equivalent of the above <tag> but then with <element>. as you can see a single tag<br />
needs a lot of text. That's why this convenience <tag was created.<br />
<pre><br />
<element id="&lt;body" pattern="&lt;body" highlight="tag" starts_block="1"><br />
<context symbols="&amp;gt;\&amp;quot;=' &amp;#9;&amp;#10;&amp;#13;" ><br />
<element pattern="style" highlight="attribute" /><br />
<element pattern="class" highlight="attribute" /><br />
<element pattern="id" highlight="attribute" /><br />
<element id="__internal_tag_string_d__" pattern="&amp;quot;[^&amp;quot;]*&amp;quot;" is_regex="1" highlight="string" /><br />
<element id="__internal_tag_string_s__" pattern="'[^']*'" is_regex="1" highlight="string" /><br />
<element pattern="/&gt;" ends_context="1" highlight="tag" /><br />
</context><br />
</element><br />
<element pattern="&lt;/body&lt;" highlight="tag" ends_block="1" blockstartelement="&lt;body" /><br />
</pre><br />
<br />
==== starting a new context ====<br />
a <tag> may also start a new context just as <element> does<br />
<br />
==== auto completion ====<br />
next example shows autocompletion for tags<br />
<pre><br />
<tag name="img" attributes="style,class,id,src,width,height"<br />
autocomplete_append="&gt;" attrib_autocomplete_append="=&amp;quot;&amp;quot;" attrib_autocomplete_backup_cursor="2"/></pre><br />
<br />
a <tag> automatically autocompletes. it also has an 'attrib_autocomplete_append' atribute.<br />
<br />
next example shows auto closing options for tags<br />
<pre><tag name="br" no_close="1" /></pre><br />
<br />
a <tag> will automaticaly suggest </tag> for autocompletion (if not disabled for the complete language file).<br />
some tags don't need a closing tag because they close themselves <tag />. use no_close="1"<br />
typical tags in html are for example br img hr input<br />
<br />
next example shows how to enable SGML short tags. This suggests to the autocompletion that this tag<br />
is not closed and also does not end on '/>' (thus no proper xml syntax).<br />
instead of suggesting &lt;br /> it will suggest &lt;br> <br />
<pre><tag name="img" sgml_shorttag="1" /></pre><br />
<br />
in XML or XHTML a tag always needs to be closed, either <img /> or <img></img><br />
in SGML <img> is also allowed. set sgml_shorttag="1" to enable this<br />
<br />
== The group tag in the definition section ==<br />
<br />
often there are many elements that need the same attribute such as highlight or autocomplete<br />
<br />
to make this easier you can group these elements inside <group>.<br />
<pre><br />
<group highlight="keyword" ><br />
<autocomplete enable="1" /><br />
<element pattern="for"/><br />
<element pattern="while"/><br />
</group><br />
</pre><br />
<br />
supported atributes are:<br />
* highlight<br />
* autocomplete<br />
* autocomplete_append<br />
* class<br />
* case_insens<br />
* is_regex<br />
==== groups for tags ====<br />
also many <tag> entries can have the same attributes, so these can also be<br />
grouped inside <group><br />
<pre><br />
<group attribhighlight="attribute" highlight="tag" attrib_autocomplete_append="=&quot;&quot;" ><br />
<autocomplete append="&gt;" /><br />
<tag name="p" attributes="style,id,width"/><br />
<tag name="div" attributes="style,id" /><br />
</group><br />
</pre><br />
<br />
supported attributes are:<br />
- highlight<br />
- attribhighlight<br />
- attrib_autocomplete_append<br />
- class<br />
<br />
==== Autocomplete options in groups ====<br />
<br />
Suppose you have a lot of <element /> tags where you want to make auto completion configurable. You do not need to add autocomplete tags to each and every <element />, you can add them to a group:<br />
<pre><group highlight="libc-function" ><br />
<autocomplete append="();" class="autocompl_with_semicolon" backup_cursor="2" /><br />
<autocomplete append="()" notclass="autocompl_with_semicolon" backup_cursor="1" /><br />
<element pattern="a64l"><reference>Encode Binary Data</reference></element><br />
<element pattern="abort"><reference>Aborting a Program</reference></element><br />
..... etc.<br />
</pre><br />
<br />
<br />
==== groups that can be disabled/enabled with an option ====<br />
<br />
a special usage of <group is to allow the user to disable/enable a section of the file.<br />
if the <header> section has <option name="allphpfunctions" default="1" description="All php functions" /><br />
we can put this option into effect like this:<br />
<pre><br />
<group class="allphpfunctions"><br />
<element pattern="mysql_query" /><br />
<element pattern="mysql_fetch_row" /><br />
<element pattern="mysql_fetch_array" /><br />
</group><br />
</pre><br />
the reverse is also supported, using the notclass attribute, this can be used to make a<br />
option that disables one section but enables a different section<br />
<pre><br />
<group notclass="mysetting"><br />
<element pattern="foo" /><br />
</group><br />
<group class="mysetting"><br />
<element pattern="bar" /><br />
</group><br />
</pre><br />
<br />
==== Advanced group class/notclass values ====<br />
<br />
Some parts of language definition files can be included in different languages. That is why there are some special options defined. The option is_LANG is always defined, where LANG is the name of the current language.<br />
<br />
For example, CSS is included in HTML and in PHP. But in CSS-in-HTML the pattern <?php should do something different than in CSS-in-HTML-in-PHP. The following example does just that:<br />
<pre><group class="is_PHP"><br />
<element idref="e.php.short.open" /><br />
</group></pre><br />
<br />
== Advanced option: conditional execution ==<br />
<br />
Since Bluefish 2.2.7 patterns can be made "conditional", they will be still compiled in the<br />
DFA engine, but their actions (starting a context, highlighting, starting a block) are depending<br />
on a certain condition, such as if they are in a certain context or not.<br />
<br />
condition_mode=""<br />
*1 = valid if relation with context matches,<br />
*2 = invalid if relation with context matches,<br />
*3 = valid if relation with block matches<br />
*4 = invalid if relation with block matches<br />
<br />
condition_relation=""<br />
* -1 means any parent<br />
* 0 = direct parent<br />
* 1= grandparent<br />
* etc.<br />
<br />
condition_contextref="" <br />
* refers to the id of a context or block-starting-element<br />
<br />
<br />
An example is used in the CSS highlighting include file. If it is included in a CSS file this pattern is not executed, but if this is included in a HTML HEAD STYLE section, this pattern will be executed: <br />
<pre><br />
<element id="end-style-tag" pattern="&lt;/style&gt;" highlight="<br />
html-tag" ends_context="3" <br />
condition_mode="1" condition_relation="2" condition_contextref="c.html.css.main"/><br />
</pre><br />
== Advanced option: identifier autocompletion ==<br />
An identifier is a part of the syntax that is not pre-defined (such as a function name), but defined in the context of a document (such as a variable name). Bluefish can add identifiers to an autocompletion list, so they can be offered to the user in the autocompletion popup.<br />
<br />
= Deep understanding of the Bluefish syntax scanning =<br />
<br />
'''You do not need to understand this to change or write a language file, this is provided for deeper understanding of the internals'''<br />
<br />
== Design considerations ==<br />
<br />
*syntax highlighting should be pretty fast; the user continuously changes the syntax while typing, and the highlighting should keep up with that<br />
*syntax should be defined in a language file; new languages can be added and language files can be updated without a change in the scanning engine<br />
*the language file should not contain any highlighting colors, it should map to textstyles that the user can define, such that all languages have a similar look<br />
*the syntax scanning should support all kinds of languages, markup such as html and xml, and programming languages like javascript and php, and it should be capable of handling thousands of patterns.<br />
*the syntax scanning should be context-aware (in a comment? in a php block? in a CSS block?) and block-aware (&lt;p&gt; opened, &lt;b&gt; opened, &lt;/b&gt; closed etc.)<br />
*the widget should allow context-aware autocompletion<br />
*scanning large blocks of text should not block/freeze the gui<br />
<br />
We have one additional constraint: Because we wanted to use GtkTextView as the base class the actual highlighting cannot be done in a separate thread or in the background (we have to set GtkTextTag’s from the main thread).<br />
<br />
This resulted in the following high-level design:<br />
<br />
*we use a DFA engine to scan syntax because it is very fast (O(n) on the input data) independent from the number of patterns (O(1) on the number of patterns)1<br />
*because we want to scan context-sensitive we compile a DFA table for each context<br />
*the complete DFA is in a single continuous memory block to maximize CPU cache and minimize memory paging effects<br />
*for each context we also compile a GCompletion with all possible autocompletion strings in that context<br />
*all language file parsing and compiling is done in a separate thread so we exploit the possibilities of multi-core computers<br />
*we keep a stack of contexts and a stack of blocks during the scanning run<br />
*we scan for syntax in short timeslots that block the UI, but after the short timeslot we return control back to the gtk main loop.<br />
*we keep track of text that needs scanning in a list-like structure <br />
*on text change we simply mark the changed area in this list-like structure and set an idle callback to resume scanning<br />
*we should be capable to resume scanning on any given position<br />
**that means that we should be able to reconstruct the block-stack and the context-stack at any given position<br />
**a very fast way to look-up a given context-stack and block-stack at a given position is if we keep them in a balanced-tree which scales O(log n) on the number of stored positions. But we are in a worst-case situation for normal binary-tree’s: we insert data in sorted order. Glib has a nice Treap implementation that we use that is much better when data is inserted in sorted order 2<br />
*for autocompletion we look-up the position in the balanced tree, peek at the context stack to get the current context, and use the corresponding GCompletion to find the possible strings<br />
<br />
== Scanning with a DFA table ==<br />
<br />
For background on a DFA engine see http://en.wikipedia.org/wiki/Deterministic_finite_automaton<br />
<br />
Lets use a very simple language file:<br />
<br />
<context symbols=" ;(){}[]:\&#34;\\',&amp;gt;&amp;lt;*&amp;amp;^%!+=-|/?#&amp;#9;&amp;#10;&amp;#13;." dump_dfa_chars="()*;char" dump_dfa_run="1"><br />
<element pattern="(" id="lparen" starts_block="1" highlight="brackets" /><br />
<element pattern=")" highlight="brackets" ends_block="1" blockstartelement="lparen" /><br />
<element pattern="char" highlight="function" /><br />
</context><br />
<br />
Bluefish compiles each context into a DFA table. Because we use the attribute ''dump_dfa_chars'' Bluefish will show the DFA table for these characters in the terminal output:<br />
<br />
***************** print subset of DFA table for context 1<br />
'(' ')' '*' ';' 'c' 'h' 'a' 'r' : match<br />
0: 2 3 0 0 4 1 1 1 : 0 this is the startstate<br />
1: 0 0 0 0 1 1 1 1 : 0 this is the identstate<br />
2: 0 0 0 0 0 0 0 0 : 1 (<br />
3: 0 0 0 0 0 0 0 0 : 2 )<br />
4: 0 0 0 0 1 5 1 1 : 0<br />
5: 0 0 0 0 1 1 6 1 : 0<br />
6: 0 0 0 0 1 1 1 7 : 0<br />
7: 0 0 0 0 1 1 1 1 : 3 char<br />
*****************<br />
<br />
Lets scan the following text with this table:<br />
<br />
char *rc_char(char*chara);<br />
<br />
Because we used the attribute ''dump_dfa_run'' we get to see how the scanner walks trough this table. Bluefish always starts at state 0, the startstate:<br />
<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: ' ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: ' ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'r ' in 0 makes 1 --> nothing matches, go to identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: '_ ' in 1 makes 1 .....identstate<br />
context 1: 'c ' in 1 makes 1 .....identstate<br />
context 1: 'h ' in 1 makes 1 .....identstate<br />
context 1: 'a ' in 1 makes 1 .....identstate<br />
context 1: 'r ' in 1 makes 1 .....identstate<br />
context 1: '( ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '( ' in 0 makes 2<br />
context 1: 'c ' in 2 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (()<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: '* ' in 7 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match (char)<br />
context 1: '* ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: 'c ' in 0 makes 4<br />
context 1: 'h ' in 4 makes 5<br />
context 1: 'a ' in 5 makes 6<br />
context 1: 'r ' in 6 makes 7<br />
context 1: 'a ' in 7 makes 1 --> nothing matches, go to identstate<br />
context 1: ') ' in 1 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: ') ' in 0 makes 3<br />
context 1: '; ' in 3 makes 0 --> a symbol or the pattern ends on a symbol, the previous was a match ())<br />
context 1: '; ' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
context 1: '\0' in 0 makes 0 --> restart scanning (found a symbol, no match?)<br />
<br />
== Code documentation ==<br />
<br />
If you want a deep understanding how the syntax scanner works, please read the documentation included in the Bluefish source code<br />
<br />
* src/bftextview2.h the scanner overall design is described, and some of the types are defined<br />
* src/bftextview2_private.h most internal types are described<br />
* src/bftextview2.c has the code for the widget which invokes the scanner, the spell checker<br />
* src/bftextview2_langmgr.c has the code for the parsing of the language file, which invokes the DFA compiler<br />
* src/bftextview2_patcompile.c has the code that compiles the DFA table<br />
* src/bftextview2_scanner.c has the code for the scanner and it's cache<br />
* src/bftextview2_autocomp.c has the auto-completion code<br />
* src/bftextview2_markregion.c has the code to keep track of which part of the document has changes and needs rescanning<br />
* src/bftextview2_spell.c has the code to do context-sensitive spell checking<br />
* src/bftextview2_identifier.c has the code to keep track of identifiers (for example names of user defined variables) so you can jump to them, or autocomplete them.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Keyboard_shortcuts&diff=2648Keyboard shortcuts2015-02-14T09:54:34Z<p>OlivierSessink: /* Navigation */</p>
<hr />
<div><br />
= File handling =<br />
<br />
<ctrl>s = save<br />
<ctrl>o = open<br />
<ctrl>w = close document<br />
<shift><ctrl>w = close all documents in current window<br />
<br />
= Navigation =<br />
<br />
* <ctrl><pageup> = document tab to the left<br />
* <ctrl><pageup> = document tab to the right<br />
* <ctrl><tab> = previous document tab<br />
* <ctrl><tab><tab> = before-previous document tab (etc.)<br />
* <ctrl>l = goto line<br />
<br />
* <ctrl>+ = zoom in (font size bigger)<br />
* <ctrl>- = zoom out (font size smaller)<br />
<br />
* <ctrl>f = search<br />
* <ctrl><shift>f = search for currently selected text (select some text and press this key-combo to search for it)<br />
* <ctrl>h = advanced search and replace<br />
<br />
= Editing =<br />
<br />
<shift><ctrl>b = select current block<br />
<shift><ctrl>bb = select parent block (hold shift and control, press b two times)<br />
<shift><ctrl>bbb = select parent of parent block (etc.)<br />
<br />
<ctrl>z = undo<br />
<shift><ctrl>z = redo<br />
<br />
<ctrl>d = duplicate line<br />
<ctrl>y = duplicate line<br />
<ctrl><up> = move line up<br />
<ctrl><down> = move line down<br />
<br />
<ctrl>. = indent selection / indent current line<br />
<ctrl>, = unindent selection / unindent current line<br />
<br />
<shift><ctrl>c = toggle comment<br />
<br />
= AutoCompletion =<br />
<ctrl><space> = popup all possible values in current context <br />
<tab> in a popup = command-completion style<br />
<arrow up> or <arrow down> = select an item<br />
<enter> = insert the current selected item<br />
<esc> = close the popup</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Keyboard_shortcuts&diff=2647Keyboard shortcuts2015-02-14T09:53:08Z<p>OlivierSessink: </p>
<hr />
<div><br />
= File handling =<br />
<br />
<ctrl>s = save<br />
<ctrl>o = open<br />
<ctrl>w = close document<br />
<shift><ctrl>w = close all documents in current window<br />
<br />
= Navigation =<br />
<br />
<ctrl><pageup> = document tab to the left<br />
<ctrl><pageup> = document tab to the right<br />
<ctrl><tab> = previous document tab<br />
<ctrl><tab><tab> = before-previous document tab (etc.)<br />
<ctrl>l = goto line<br />
<br />
<ctrl>+ = zoom in (font size bigger)<br />
<ctrl>- = zoom out (font size smaller)<br />
<br />
<ctrl>f = search<br />
<ctrl><shift>f = search for currently selected text (select some text and press this key-combo to search for it)<br />
<ctrl>h = advanced search and replace<br />
<br />
= Editing =<br />
<br />
<shift><ctrl>b = select current block<br />
<shift><ctrl>bb = select parent block (hold shift and control, press b two times)<br />
<shift><ctrl>bbb = select parent of parent block (etc.)<br />
<br />
<ctrl>z = undo<br />
<shift><ctrl>z = redo<br />
<br />
<ctrl>d = duplicate line<br />
<ctrl>y = duplicate line<br />
<ctrl><up> = move line up<br />
<ctrl><down> = move line down<br />
<br />
<ctrl>. = indent selection / indent current line<br />
<ctrl>, = unindent selection / unindent current line<br />
<br />
<shift><ctrl>c = toggle comment<br />
<br />
= AutoCompletion =<br />
<ctrl><space> = popup all possible values in current context <br />
<tab> in a popup = command-completion style<br />
<arrow up> or <arrow down> = select an item<br />
<enter> = insert the current selected item<br />
<esc> = close the popup</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Hidden_features&diff=2646Hidden features2015-02-14T09:49:52Z<p>OlivierSessink: </p>
<hr />
<div>{{Man2top<br />
|lang=en<br />
|rev=2.0.2<br />
|st=v<br />
|Title=Hidden features<br />
|prev=Autocompletion<br />
|Subtitle=More than a Text Editor<br />
|next=Spell checker<br />
}}<br />
<br />
=Really hidden features=<br />
<br />
* <ctrl><space> will start autocompletion even on an empty string<br />
* if there is an autocompletion popup, <tab> will do autocompletion similar to command-line-completion<br />
* you can change shortcut-key combinations, simply move your mouse over a menu item and press a key combination to set it<br />
* double-click in the margin to add a bookmark<br />
* move your mouse over highlighted syntax to get reference information if available (currently PHP functions are the best examples)<br />
* right click on a document tab to see a listing of all opened documents<br />
* <ctrl>mousewheel will change up/down the font size (a zoom like effect)<br />
<br />
=GTK hidden features=<br />
;<shift><control>u :''Unicode input'': type the four numbers of the hex code and finish with Enter.<br />
<br />
=Often overlooked features=<br />
<br />
* F9 will hide/show the side panel<br />
* F11 will make bluefish go fullscreen (nice on your netbook)<br />
<br />
<br />
{{Man2bottom<br />
|prev=Autocompletion<br />
|up=Indenting<br />
|next=Spell checker<br />
|prevname=Autocompletion<br />
|nextname=Spell checker<br />
}}</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Installing_Bluefish&diff=2640Installing Bluefish2015-02-06T09:37:58Z<p>OlivierSessink: /* Installing the very latest on Ubuntu Linux */</p>
<hr />
<div>= Installing Bluefish on Debian GNU/Linux =<br />
<br />
== Installing the release that is part of Debian / Ubuntu / Mint / etc. ==<br />
<br />
Use<br />
<br />
sudo apt-get install bluefish<br />
sudo aptitude install bluefish<br />
<br />
or any other frontend for the package manager such as synaptic or simply "add / remove programs".<br />
<br />
== Installing the very latest release on Debian ==<br />
<br />
=== Installing the very latest release on Debian 7.0 (Wheezy/Stable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/stable-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian wheezy-backports main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian stable-backports main<br />
<br />
And install the package via:<br />
<br />
apt-get -t wheezy-backports install bluefish<br />
<br />
Report any bugs to the Debian bugtracker.<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
=== Installing the very latest release on Debian 6.0 (Squeeze/Oldstable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/stable-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports squeeze-backports-sloppy main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports oldstable-backports-sloppy main<br />
<br />
And install the package via:<br />
<br />
apt-get -t squeeze-backports-sloppy install bluefish<br />
<br />
This version is built with the GTK+ 2 libraries. Report any bugs to the Debian bugtracker.<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
== Installing the very latest on Ubuntu Linux ==<br />
<br />
You'll find recent packages of '''bluefish''' in [https://launchpad.net/~klaus-vormweg/+archive/bluefish the Bluefish PPA maintained by Klaus Vormweg]. Follow the instructions given there to add this repository. Then '''bluefish''' can be updated to its latest release:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
=== Removing obsolete debian.wgdd.de entries from sources.list ===<br />
<br />
The http://debian.wgdd.de/ repository no longer provides packages of bluefish. The above steps make the following entries to either ''/etc/apt/sources.list'' or ''/etc/apt/sources.list.d/debian.wgdd.de_*.list'' or any other file in ''/etc/apt/sources.list.d/'' obsolete. You can safely remove any references to the http://debian.wgdd.de repository, that may look like these:<br />
<br />
deb http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb-src http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb http://debian.wgdd.de/debian stable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian stable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb-src http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb http://debian.wgdd.de/debian oldstable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian oldstable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
deb-src http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
<br />
and update your system:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Also the '''wgdd-archive-keyring''' package then is obsolete together with the repository keyring. If you have the package installed, do:<br />
<br />
sudo apt-get autoremove --purge wgdd-archive-keyring<br />
<br />
... or if you only had the key:<br />
<br />
sudo apt-key del E394D996<br />
<br />
= Installing Bluefish on Fedora Linux =<br />
<br />
=== Installing the version distributed by Fedora ===<br />
<br />
yum install bluefish<br />
<br />
=== Installing the very latest on Fedora with yum ===<br />
<br />
To enable a bluefish-release yum repository download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-release.repo bluefish-release.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19 and Fedora 20. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br/><br />
<br />
=== Installing development versions on Fedora with yum ===<br />
<br />
While care is taken to keep development versions very stable and usable, development versions may crash, contain data eating bugs and incomplete features.<br/><br />
Please report any bugs you might find in [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Bluefish bugzilla]<br/><br />
<br />
If you wish to test the bleeding edge versions of Bluefish currently under development download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-svn.repo bluefish-svn.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19, 20 and 21. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br />
<br />
=== Browsable Yum repo's for Fedora ===<br />
<br />
These pages were created using repoview.<br />
<br />
Fedora 19 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/x86_64/repoview/ x86_64]<br />
<br />
Fedora 20 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/x86_64/repoview/ x86_64]<br />
<br />
= Installing Bluefish on RHEL/CentOS 6.5 =<br />
<br />
=== Installing the very latest on RHEL/CentOS 6.5 ===<br />
<br />
Bluefish packages for RHEL/CentOS 6.5 are available at the links below for i386 and x86_64.<br/><br />
These packages require version 6.5. Previous versions prior to 6.5 had GTK+ 2.18.x.<br/><br />
RHEL/CentOS 6.5 has GTK+ 2.20.x which is the minimum version required to build current versions of Bluefish.<br />
<br />
All packages are built using mock. All packages are signed with this gpg [http://bluefish.linuxexperience.net/downloads/fedora/RPM-GPG-KEY-bluefish-svn.asc key].<br />
<br />
<br />
Required for RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-2.2.6-1.el6.i686.rpm bluefish-2.2.6-1.el6.i686.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-shared-data-2.2.6-1.el6.noarch.rpm bluefish-shared-data-2.2.6-1.el6.noarch.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-2.2.6-1.el6.x86_64.rpm bluefish-2.2.6-1.el6.x86_64.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-shared-data-2.2.6-1.el6.noarch.rpm bluefish-shared-data-2.2.6-1.el6.noarch.rpm]<br />
<br />
Optional debug info RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/i386/bluefish-debuginfo-2.2.6-1.el6.i686.rpm bluefish-debuginfo-2.2.6-1.el6.i686.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/x86_64/bluefish-debuginfo-2.2.6-1.el6.x86_64.rpm bluefish-debuginfo-2.2.6-1.el6.x86_64.rpm]<br />
<br />
= Installing Bluefish on openSUSE =<br />
<br />
Bluefish is available in the main repository. Launch YaST and search for "bluefish" to find and select the appropriate package to install.<br />
<br />
This process is also automated through 1-Click-Install on the openSUSE Build Service: https://software.opensuse.org/package/bluefish<br />
<br />
= Installing Bluefish on AltLinux =<br />
<br />
<br />
= Installing Bluefish on Slackware =<br />
<br />
= Installing Bluefish on Mac OS X =<br />
<br />
Download http://www.bennewitz.com/bluefish/stable/binaries/macosx/Bluefish-2.2.5-2.dmg from http://www.bennewitz.com/bluefish/stable/binaries/macosx/, open it and drag the bluefish icon onto Applications.<br />
<br />
In Mavericks there is a system setting called ''Gatekeeper'' that only allows you to install packages from Apple-identified developers. Bluefish is not distributed through the Apple app store, so you will have to workaround that setting.<br />
<br />
Use the contextual menu (e.g. secondary-click button), and you'll see a menu with "Open" in it.<br />
This will present you with a dialogue box, asking you for permission to run the software.<br />
You will only be asked this the first time.<br />
<br />
Alternatively, the ''Gatekeeper'' setting can be disabled. For information, see: <br />
https://kb.wisc.edu/helpdesk/page.php?id=25443 or http://support.apple.com/kb/ht5290<br />
<br />
= Installing Bluefish on Windows XP or newer =<br />
<br />
=== Installing 2.2.7 ===<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
The installer will require internet access to download GTK+ and any spell check dictionaries. Please note that the internet-enabled setup may fail if the installer is run from a network share. See below for instructions for internet-less installation.<br />
<br />
==== Installing without Internet Access ====<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
Download the GTK+ 2.24.8 installer (from the gtk-win project): <br />
http://downloads.sourceforge.net/gtk-win/gtk2-runtime-2.24.8-2011-12-03-ash.exe?download<br />
<br />
Download any language dictionaries you wish to be able to install: <br />
http://www.muleslow.net/files/aspell/lang/<br />
<br />
Place the files in a new directory named 'redist' in the same directory as the Bluefish installer.<br />
e.x.<br />
Bluefish\<br />
Bluefish\Bluefish-2.2.7-setup.exe<br />
Bluefish\redist\gtk2-runtime-2.24.8-2011-12-03-ash.exe<br />
Bluefish\redist\aspell6-en-7.1-0.tbz2<br />
<br />
The installer will fall back on downloading the files if they are not found in the redist folder, or if the checksum of the local copy is invalid.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Installing_Bluefish&diff=2639Installing Bluefish2015-02-06T09:36:55Z<p>OlivierSessink: /* Removing obsolete entries from sources.list */</p>
<hr />
<div>= Installing Bluefish on Debian GNU/Linux =<br />
<br />
== Installing the release that is part of Debian / Ubuntu / Mint / etc. ==<br />
<br />
Use<br />
<br />
sudo apt-get install bluefish<br />
sudo aptitude install bluefish<br />
<br />
or any other frontend for the package manager such as synaptic or simply "add / remove programs".<br />
<br />
== Installing the very latest release on Debian ==<br />
<br />
=== Installing the very latest release on Debian 7.0 (Wheezy/Stable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/stable-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian wheezy-backports main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian stable-backports main<br />
<br />
And install the package via:<br />
<br />
apt-get -t wheezy-backports install bluefish<br />
<br />
Report any bugs to the Debian bugtracker.<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
=== Installing the very latest release on Debian 6.0 (Squeeze/Oldstable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/stable-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports squeeze-backports-sloppy main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports oldstable-backports-sloppy main<br />
<br />
And install the package via:<br />
<br />
apt-get -t squeeze-backports-sloppy install bluefish<br />
<br />
This version is built with the GTK+ 2 libraries. Report any bugs to the Debian bugtracker.<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
== Installing the very latest on Ubuntu Linux ==<br />
<br />
Users of Ubuntu releases, for which bluefish doesn't get any official update by the Ubuntu team in the past had the possibility to use the [http://debian.wgdd.de/debian http://debian.wgdd.de/ubuntu] repository. This has become obsolete. You'll now find recent packages of '''bluefish''' in [https://launchpad.net/~klaus-vormweg/+archive/bluefish the Bluefish PPA maintained by Klaus Vormweg]. Follow the instructions given there to add this repository. Then '''bluefish''' can be updated to its latest release:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
=== Removing obsolete debian.wgdd.de entries from sources.list ===<br />
<br />
The http://debian.wgdd.de/ repository no longer provides packages of bluefish. The above steps make the following entries to either ''/etc/apt/sources.list'' or ''/etc/apt/sources.list.d/debian.wgdd.de_*.list'' or any other file in ''/etc/apt/sources.list.d/'' obsolete. You can safely remove any references to the http://debian.wgdd.de repository, that may look like these:<br />
<br />
deb http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb-src http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb http://debian.wgdd.de/debian stable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian stable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb-src http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb http://debian.wgdd.de/debian oldstable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian oldstable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
deb-src http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
<br />
and update your system:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Also the '''wgdd-archive-keyring''' package then is obsolete together with the repository keyring. If you have the package installed, do:<br />
<br />
sudo apt-get autoremove --purge wgdd-archive-keyring<br />
<br />
... or if you only had the key:<br />
<br />
sudo apt-key del E394D996<br />
<br />
= Installing Bluefish on Fedora Linux =<br />
<br />
=== Installing the version distributed by Fedora ===<br />
<br />
yum install bluefish<br />
<br />
=== Installing the very latest on Fedora with yum ===<br />
<br />
To enable a bluefish-release yum repository download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-release.repo bluefish-release.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19 and Fedora 20. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br/><br />
<br />
=== Installing development versions on Fedora with yum ===<br />
<br />
While care is taken to keep development versions very stable and usable, development versions may crash, contain data eating bugs and incomplete features.<br/><br />
Please report any bugs you might find in [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Bluefish bugzilla]<br/><br />
<br />
If you wish to test the bleeding edge versions of Bluefish currently under development download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-svn.repo bluefish-svn.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19, 20 and 21. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br />
<br />
=== Browsable Yum repo's for Fedora ===<br />
<br />
These pages were created using repoview.<br />
<br />
Fedora 19 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/x86_64/repoview/ x86_64]<br />
<br />
Fedora 20 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/x86_64/repoview/ x86_64]<br />
<br />
= Installing Bluefish on RHEL/CentOS 6.5 =<br />
<br />
=== Installing the very latest on RHEL/CentOS 6.5 ===<br />
<br />
Bluefish packages for RHEL/CentOS 6.5 are available at the links below for i386 and x86_64.<br/><br />
These packages require version 6.5. Previous versions prior to 6.5 had GTK+ 2.18.x.<br/><br />
RHEL/CentOS 6.5 has GTK+ 2.20.x which is the minimum version required to build current versions of Bluefish.<br />
<br />
All packages are built using mock. All packages are signed with this gpg [http://bluefish.linuxexperience.net/downloads/fedora/RPM-GPG-KEY-bluefish-svn.asc key].<br />
<br />
<br />
Required for RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-2.2.6-1.el6.i686.rpm bluefish-2.2.6-1.el6.i686.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-shared-data-2.2.6-1.el6.noarch.rpm bluefish-shared-data-2.2.6-1.el6.noarch.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-2.2.6-1.el6.x86_64.rpm bluefish-2.2.6-1.el6.x86_64.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-shared-data-2.2.6-1.el6.noarch.rpm bluefish-shared-data-2.2.6-1.el6.noarch.rpm]<br />
<br />
Optional debug info RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/i386/bluefish-debuginfo-2.2.6-1.el6.i686.rpm bluefish-debuginfo-2.2.6-1.el6.i686.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/x86_64/bluefish-debuginfo-2.2.6-1.el6.x86_64.rpm bluefish-debuginfo-2.2.6-1.el6.x86_64.rpm]<br />
<br />
= Installing Bluefish on openSUSE =<br />
<br />
Bluefish is available in the main repository. Launch YaST and search for "bluefish" to find and select the appropriate package to install.<br />
<br />
This process is also automated through 1-Click-Install on the openSUSE Build Service: https://software.opensuse.org/package/bluefish<br />
<br />
= Installing Bluefish on AltLinux =<br />
<br />
<br />
= Installing Bluefish on Slackware =<br />
<br />
= Installing Bluefish on Mac OS X =<br />
<br />
Download http://www.bennewitz.com/bluefish/stable/binaries/macosx/Bluefish-2.2.5-2.dmg from http://www.bennewitz.com/bluefish/stable/binaries/macosx/, open it and drag the bluefish icon onto Applications.<br />
<br />
In Mavericks there is a system setting called ''Gatekeeper'' that only allows you to install packages from Apple-identified developers. Bluefish is not distributed through the Apple app store, so you will have to workaround that setting.<br />
<br />
Use the contextual menu (e.g. secondary-click button), and you'll see a menu with "Open" in it.<br />
This will present you with a dialogue box, asking you for permission to run the software.<br />
You will only be asked this the first time.<br />
<br />
Alternatively, the ''Gatekeeper'' setting can be disabled. For information, see: <br />
https://kb.wisc.edu/helpdesk/page.php?id=25443 or http://support.apple.com/kb/ht5290<br />
<br />
= Installing Bluefish on Windows XP or newer =<br />
<br />
=== Installing 2.2.7 ===<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
The installer will require internet access to download GTK+ and any spell check dictionaries. Please note that the internet-enabled setup may fail if the installer is run from a network share. See below for instructions for internet-less installation.<br />
<br />
==== Installing without Internet Access ====<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
Download the GTK+ 2.24.8 installer (from the gtk-win project): <br />
http://downloads.sourceforge.net/gtk-win/gtk2-runtime-2.24.8-2011-12-03-ash.exe?download<br />
<br />
Download any language dictionaries you wish to be able to install: <br />
http://www.muleslow.net/files/aspell/lang/<br />
<br />
Place the files in a new directory named 'redist' in the same directory as the Bluefish installer.<br />
e.x.<br />
Bluefish\<br />
Bluefish\Bluefish-2.2.7-setup.exe<br />
Bluefish\redist\gtk2-runtime-2.24.8-2011-12-03-ash.exe<br />
Bluefish\redist\aspell6-en-7.1-0.tbz2<br />
<br />
The installer will fall back on downloading the files if they are not found in the redist folder, or if the checksum of the local copy is invalid.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Installing_Bluefish&diff=2638Installing Bluefish2015-02-06T09:36:28Z<p>OlivierSessink: /* Installing the very latest on Ubuntu Linux */</p>
<hr />
<div>= Installing Bluefish on Debian GNU/Linux =<br />
<br />
== Installing the release that is part of Debian / Ubuntu / Mint / etc. ==<br />
<br />
Use<br />
<br />
sudo apt-get install bluefish<br />
sudo aptitude install bluefish<br />
<br />
or any other frontend for the package manager such as synaptic or simply "add / remove programs".<br />
<br />
== Installing the very latest release on Debian ==<br />
<br />
=== Installing the very latest release on Debian 7.0 (Wheezy/Stable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/stable-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian wheezy-backports main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian stable-backports main<br />
<br />
And install the package via:<br />
<br />
apt-get -t wheezy-backports install bluefish<br />
<br />
Report any bugs to the Debian bugtracker.<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
=== Installing the very latest release on Debian 6.0 (Squeeze/Oldstable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/stable-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports squeeze-backports-sloppy main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports oldstable-backports-sloppy main<br />
<br />
And install the package via:<br />
<br />
apt-get -t squeeze-backports-sloppy install bluefish<br />
<br />
This version is built with the GTK+ 2 libraries. Report any bugs to the Debian bugtracker.<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
== Installing the very latest on Ubuntu Linux ==<br />
<br />
Users of Ubuntu releases, for which bluefish doesn't get any official update by the Ubuntu team in the past had the possibility to use the [http://debian.wgdd.de/debian http://debian.wgdd.de/ubuntu] repository. This has become obsolete. You'll now find recent packages of '''bluefish''' in [https://launchpad.net/~klaus-vormweg/+archive/bluefish the Bluefish PPA maintained by Klaus Vormweg]. Follow the instructions given there to add this repository. Then '''bluefish''' can be updated to its latest release:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
== Removing obsolete entries from sources.list ==<br />
<br />
The http://debian.wgdd.de/ repository no longer provides packages of bluefish. The above steps make the following entries to either ''/etc/apt/sources.list'' or ''/etc/apt/sources.list.d/debian.wgdd.de_*.list'' or any other file in ''/etc/apt/sources.list.d/'' obsolete. You can safely remove any references to the http://debian.wgdd.de repository, that may look like these:<br />
<br />
deb http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb-src http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb http://debian.wgdd.de/debian stable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian stable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb-src http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb http://debian.wgdd.de/debian oldstable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian oldstable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
deb-src http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
<br />
and update your system:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Also the '''wgdd-archive-keyring''' package then is obsolete together with the repository keyring. If you have the package installed, do:<br />
<br />
sudo apt-get autoremove --purge wgdd-archive-keyring<br />
<br />
... or if you only had the key:<br />
<br />
sudo apt-key del E394D996<br />
<br />
= Installing Bluefish on Fedora Linux =<br />
<br />
=== Installing the version distributed by Fedora ===<br />
<br />
yum install bluefish<br />
<br />
=== Installing the very latest on Fedora with yum ===<br />
<br />
To enable a bluefish-release yum repository download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-release.repo bluefish-release.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19 and Fedora 20. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br/><br />
<br />
=== Installing development versions on Fedora with yum ===<br />
<br />
While care is taken to keep development versions very stable and usable, development versions may crash, contain data eating bugs and incomplete features.<br/><br />
Please report any bugs you might find in [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Bluefish bugzilla]<br/><br />
<br />
If you wish to test the bleeding edge versions of Bluefish currently under development download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-svn.repo bluefish-svn.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19, 20 and 21. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br />
<br />
=== Browsable Yum repo's for Fedora ===<br />
<br />
These pages were created using repoview.<br />
<br />
Fedora 19 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/x86_64/repoview/ x86_64]<br />
<br />
Fedora 20 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/x86_64/repoview/ x86_64]<br />
<br />
= Installing Bluefish on RHEL/CentOS 6.5 =<br />
<br />
=== Installing the very latest on RHEL/CentOS 6.5 ===<br />
<br />
Bluefish packages for RHEL/CentOS 6.5 are available at the links below for i386 and x86_64.<br/><br />
These packages require version 6.5. Previous versions prior to 6.5 had GTK+ 2.18.x.<br/><br />
RHEL/CentOS 6.5 has GTK+ 2.20.x which is the minimum version required to build current versions of Bluefish.<br />
<br />
All packages are built using mock. All packages are signed with this gpg [http://bluefish.linuxexperience.net/downloads/fedora/RPM-GPG-KEY-bluefish-svn.asc key].<br />
<br />
<br />
Required for RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-2.2.6-1.el6.i686.rpm bluefish-2.2.6-1.el6.i686.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-shared-data-2.2.6-1.el6.noarch.rpm bluefish-shared-data-2.2.6-1.el6.noarch.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-2.2.6-1.el6.x86_64.rpm bluefish-2.2.6-1.el6.x86_64.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-shared-data-2.2.6-1.el6.noarch.rpm bluefish-shared-data-2.2.6-1.el6.noarch.rpm]<br />
<br />
Optional debug info RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/i386/bluefish-debuginfo-2.2.6-1.el6.i686.rpm bluefish-debuginfo-2.2.6-1.el6.i686.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/x86_64/bluefish-debuginfo-2.2.6-1.el6.x86_64.rpm bluefish-debuginfo-2.2.6-1.el6.x86_64.rpm]<br />
<br />
= Installing Bluefish on openSUSE =<br />
<br />
Bluefish is available in the main repository. Launch YaST and search for "bluefish" to find and select the appropriate package to install.<br />
<br />
This process is also automated through 1-Click-Install on the openSUSE Build Service: https://software.opensuse.org/package/bluefish<br />
<br />
= Installing Bluefish on AltLinux =<br />
<br />
<br />
= Installing Bluefish on Slackware =<br />
<br />
= Installing Bluefish on Mac OS X =<br />
<br />
Download http://www.bennewitz.com/bluefish/stable/binaries/macosx/Bluefish-2.2.5-2.dmg from http://www.bennewitz.com/bluefish/stable/binaries/macosx/, open it and drag the bluefish icon onto Applications.<br />
<br />
In Mavericks there is a system setting called ''Gatekeeper'' that only allows you to install packages from Apple-identified developers. Bluefish is not distributed through the Apple app store, so you will have to workaround that setting.<br />
<br />
Use the contextual menu (e.g. secondary-click button), and you'll see a menu with "Open" in it.<br />
This will present you with a dialogue box, asking you for permission to run the software.<br />
You will only be asked this the first time.<br />
<br />
Alternatively, the ''Gatekeeper'' setting can be disabled. For information, see: <br />
https://kb.wisc.edu/helpdesk/page.php?id=25443 or http://support.apple.com/kb/ht5290<br />
<br />
= Installing Bluefish on Windows XP or newer =<br />
<br />
=== Installing 2.2.7 ===<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
The installer will require internet access to download GTK+ and any spell check dictionaries. Please note that the internet-enabled setup may fail if the installer is run from a network share. See below for instructions for internet-less installation.<br />
<br />
==== Installing without Internet Access ====<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
Download the GTK+ 2.24.8 installer (from the gtk-win project): <br />
http://downloads.sourceforge.net/gtk-win/gtk2-runtime-2.24.8-2011-12-03-ash.exe?download<br />
<br />
Download any language dictionaries you wish to be able to install: <br />
http://www.muleslow.net/files/aspell/lang/<br />
<br />
Place the files in a new directory named 'redist' in the same directory as the Bluefish installer.<br />
e.x.<br />
Bluefish\<br />
Bluefish\Bluefish-2.2.7-setup.exe<br />
Bluefish\redist\gtk2-runtime-2.24.8-2011-12-03-ash.exe<br />
Bluefish\redist\aspell6-en-7.1-0.tbz2<br />
<br />
The installer will fall back on downloading the files if they are not found in the redist folder, or if the checksum of the local copy is invalid.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Installing_Bluefish&diff=2637Installing Bluefish2015-02-06T09:34:56Z<p>OlivierSessink: /* Installing Bluefish on Windows XP or newer */</p>
<hr />
<div>= Installing Bluefish on Debian GNU/Linux =<br />
<br />
== Installing the release that is part of Debian / Ubuntu / Mint / etc. ==<br />
<br />
Use<br />
<br />
sudo apt-get install bluefish<br />
sudo aptitude install bluefish<br />
<br />
or any other frontend for the package manager such as synaptic or simply "add / remove programs".<br />
<br />
== Installing the very latest release on Debian ==<br />
<br />
=== Installing the very latest release on Debian 7.0 (Wheezy/Stable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/stable-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian wheezy-backports main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian stable-backports main<br />
<br />
And install the package via:<br />
<br />
apt-get -t wheezy-backports install bluefish<br />
<br />
Report any bugs to the Debian bugtracker.<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
=== Installing the very latest release on Debian 6.0 (Squeeze/Oldstable) ===<br />
<br />
Recent packages for bluefish are available from the [https://packages.debian.org/source/stable-backports/bluefish official Debian backports archive] and can be installed by following the instructions given [http://backports.debian.org/Instructions/ here]. The entry would look like this:<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports squeeze-backports-sloppy main<br />
<br />
or<br />
<br />
deb http://YOURMIRROR.debian.org/debian-backports oldstable-backports-sloppy main<br />
<br />
And install the package via:<br />
<br />
apt-get -t squeeze-backports-sloppy install bluefish<br />
<br />
This version is built with the GTK+ 2 libraries. Report any bugs to the Debian bugtracker.<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
== Installing the very latest on Ubuntu Linux ==<br />
<br />
Users of Ubuntu releases, for which bluefish doesn't get any official update by the Ubuntu team in the past had the possibility to use the [http://debian.wgdd.de/debian http://debian.wgdd.de/ubuntu] repository. This has become obsolete. You'll now find recent packages of '''bluefish''' in this [https://launchpad.net/~klaus-vormweg/+archive/bluefish PPA]. Follow the instrcutions given there to add this repository. Then '''bluefish''' can be updated to its latest release:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Please note, that the http://debian.wgdd.de repository has become obsolete. See below, how to clean your system.<br />
<br />
== Removing obsolete entries from sources.list ==<br />
<br />
The http://debian.wgdd.de/ repository no longer provides packages of bluefish. The above steps make the following entries to either ''/etc/apt/sources.list'' or ''/etc/apt/sources.list.d/debian.wgdd.de_*.list'' or any other file in ''/etc/apt/sources.list.d/'' obsolete. You can safely remove any references to the http://debian.wgdd.de repository, that may look like these:<br />
<br />
deb http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb-src http://debian.wgdd.de/debian wheezy main contrib non-free<br />
deb http://debian.wgdd.de/debian stable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian stable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb-src http://debian.wgdd.de/debian squeeze main contrib non-free<br />
deb http://debian.wgdd.de/debian oldstable main contrib non-free<br />
deb-src http://debian.wgdd.de/debian oldstable main contrib non-free<br />
<br />
deb http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
deb-src http://debian.wgdd.de/ubuntu UBUNTU_VERSION_HERE main restricted universe multiverse <br />
<br />
and update your system:<br />
<br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
<br />
Also the '''wgdd-archive-keyring''' package then is obsolete together with the repository keyring. If you have the package installed, do:<br />
<br />
sudo apt-get autoremove --purge wgdd-archive-keyring<br />
<br />
... or if you only had the key:<br />
<br />
sudo apt-key del E394D996<br />
<br />
= Installing Bluefish on Fedora Linux =<br />
<br />
=== Installing the version distributed by Fedora ===<br />
<br />
yum install bluefish<br />
<br />
=== Installing the very latest on Fedora with yum ===<br />
<br />
To enable a bluefish-release yum repository download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-release.repo bluefish-release.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19 and Fedora 20. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br/><br />
<br />
=== Installing development versions on Fedora with yum ===<br />
<br />
While care is taken to keep development versions very stable and usable, development versions may crash, contain data eating bugs and incomplete features.<br/><br />
Please report any bugs you might find in [https://bugzilla.gnome.org/enter_bug.cgi?product=bluefish Bluefish bugzilla]<br/><br />
<br />
If you wish to test the bleeding edge versions of Bluefish currently under development download the [http://bluefish.linuxexperience.net/downloads/fedora/bluefish-svn.repo bluefish-svn.repo] file.<br/><br />
Place this repo file in /etc/yum.repos.d<br/><br />
<br />
Then you can install normally with...<br />
<br />
yum install bluefish<br />
<br />
Packages are currently provided for Fedora 19, 20 and 21. Packages are provided for both i386 and x86_64.<br/><br />
All packages are built using mock. All packages are signed. You will be prompted to download the GPG key.<br />
<br />
=== Browsable Yum repo's for Fedora ===<br />
<br />
These pages were created using repoview.<br />
<br />
Fedora 19 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/19/x86_64/repoview/ x86_64]<br />
<br />
Fedora 20 - Release<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/i386/repoview/ i386]<br />
* [http://bluefish.linuxexperience.net/downloads/fedora/release/20/x86_64/repoview/ x86_64]<br />
<br />
= Installing Bluefish on RHEL/CentOS 6.5 =<br />
<br />
=== Installing the very latest on RHEL/CentOS 6.5 ===<br />
<br />
Bluefish packages for RHEL/CentOS 6.5 are available at the links below for i386 and x86_64.<br/><br />
These packages require version 6.5. Previous versions prior to 6.5 had GTK+ 2.18.x.<br/><br />
RHEL/CentOS 6.5 has GTK+ 2.20.x which is the minimum version required to build current versions of Bluefish.<br />
<br />
All packages are built using mock. All packages are signed with this gpg [http://bluefish.linuxexperience.net/downloads/fedora/RPM-GPG-KEY-bluefish-svn.asc key].<br />
<br />
<br />
Required for RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-2.2.6-1.el6.i686.rpm bluefish-2.2.6-1.el6.i686.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/i386/bluefish-shared-data-2.2.6-1.el6.noarch.rpm bluefish-shared-data-2.2.6-1.el6.noarch.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-2.2.6-1.el6.x86_64.rpm bluefish-2.2.6-1.el6.x86_64.rpm]<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/x86_64/bluefish-shared-data-2.2.6-1.el6.noarch.rpm bluefish-shared-data-2.2.6-1.el6.noarch.rpm]<br />
<br />
Optional debug info RHEL/CentOS 6.5..<br />
<br />
i386<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/i386/bluefish-debuginfo-2.2.6-1.el6.i686.rpm bluefish-debuginfo-2.2.6-1.el6.i686.rpm]<br />
<br />
x86_64<br />
* [http://bluefish.linuxexperience.net/downloads/epel6/release/debug/x86_64/bluefish-debuginfo-2.2.6-1.el6.x86_64.rpm bluefish-debuginfo-2.2.6-1.el6.x86_64.rpm]<br />
<br />
= Installing Bluefish on openSUSE =<br />
<br />
Bluefish is available in the main repository. Launch YaST and search for "bluefish" to find and select the appropriate package to install.<br />
<br />
This process is also automated through 1-Click-Install on the openSUSE Build Service: https://software.opensuse.org/package/bluefish<br />
<br />
= Installing Bluefish on AltLinux =<br />
<br />
<br />
= Installing Bluefish on Slackware =<br />
<br />
= Installing Bluefish on Mac OS X =<br />
<br />
Download http://www.bennewitz.com/bluefish/stable/binaries/macosx/Bluefish-2.2.5-2.dmg from http://www.bennewitz.com/bluefish/stable/binaries/macosx/, open it and drag the bluefish icon onto Applications.<br />
<br />
In Mavericks there is a system setting called ''Gatekeeper'' that only allows you to install packages from Apple-identified developers. Bluefish is not distributed through the Apple app store, so you will have to workaround that setting.<br />
<br />
Use the contextual menu (e.g. secondary-click button), and you'll see a menu with "Open" in it.<br />
This will present you with a dialogue box, asking you for permission to run the software.<br />
You will only be asked this the first time.<br />
<br />
Alternatively, the ''Gatekeeper'' setting can be disabled. For information, see: <br />
https://kb.wisc.edu/helpdesk/page.php?id=25443 or http://support.apple.com/kb/ht5290<br />
<br />
= Installing Bluefish on Windows XP or newer =<br />
<br />
=== Installing 2.2.7 ===<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
The installer will require internet access to download GTK+ and any spell check dictionaries. Please note that the internet-enabled setup may fail if the installer is run from a network share. See below for instructions for internet-less installation.<br />
<br />
==== Installing without Internet Access ====<br />
Download the latest Bluefish installer from the main download server: <br />
http://www.bennewitz.com/bluefish/stable/binaries/win32/<br />
<br />
Download the GTK+ 2.24.8 installer (from the gtk-win project): <br />
http://downloads.sourceforge.net/gtk-win/gtk2-runtime-2.24.8-2011-12-03-ash.exe?download<br />
<br />
Download any language dictionaries you wish to be able to install: <br />
http://www.muleslow.net/files/aspell/lang/<br />
<br />
Place the files in a new directory named 'redist' in the same directory as the Bluefish installer.<br />
e.x.<br />
Bluefish\<br />
Bluefish\Bluefish-2.2.7-setup.exe<br />
Bluefish\redist\gtk2-runtime-2.24.8-2011-12-03-ash.exe<br />
Bluefish\redist\aspell6-en-7.1-0.tbz2<br />
<br />
The installer will fall back on downloading the files if they are not found in the redist folder, or if the checksum of the local copy is invalid.</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Keyboard_shortcuts&diff=2629Keyboard shortcuts2014-12-28T23:34:53Z<p>OlivierSessink: </p>
<hr />
<div><br />
= File handling =<br />
<br />
<ctrl>s = save<br />
<ctrl>o = open<br />
<ctrl>w = close document<br />
<shift><ctrl>w = close all documents in current window<br />
<br />
= Navigation =<br />
<br />
<ctrl><pageup> = document tab to the left<br />
<ctrl><pageup> = document tab to the right<br />
<ctrl><tab> = previous document tab<br />
<ctrl><tab><tab> = before-previous document tab (etc.)<br />
<ctrl>l = goto line<br />
<br />
<ctrl>+ = zoom in (font size bigger)<br />
<ctrl>- = zoom out (font size smaller)<br />
<br />
<ctrl>f = search<br />
<ctrl><shift>f = search for currently selected text (select some text and press this key-combo to search for it)<br />
<ctrl>h = advanced search and replace<br />
<br />
= Editing =<br />
<br />
<shift><ctrl>b = select current block<br />
<shift><ctrl>bb = select parent block (hold shift and control, press b two times)<br />
<shift><ctrl>bbb = select parent of parent block (etc.)<br />
<br />
<ctrl>z = undo<br />
<shift><ctrl>z = redo<br />
<br />
<ctrl>d = duplicate line<br />
<ctrl>y = duplicate line<br />
<ctrl><up> = move line up<br />
<ctrl><down> = move line down<br />
<br />
<ctrl>. = indent selection / indent current line<br />
<ctrl>, = unindent selection / unindent current line<br />
<br />
<shift><ctrl>c = toggle comment</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Keyboard_shortcuts&diff=2628Keyboard shortcuts2014-12-28T23:31:24Z<p>OlivierSessink: </p>
<hr />
<div><br />
= File handling =<br />
<br />
<ctrl>s = save<br />
<ctrl>o = open<br />
<shift><ctrl>w = close all documents in current window<br />
<br />
= Navigation =<br />
<br />
<ctrl><pageup> = document tab to the left<br />
<ctrl><pageup> = document tab to the right<br />
<ctrl><tab> = previous document tab<br />
<ctrl><tab><tab> = before-previous document tab (etc.)<br />
<ctrl>l = goto line<br />
<br />
<ctrl>+ = zoom in (font size bigger)<br />
<ctrl>- = zoom out (font size smaller)<br />
<br />
= Editing =<br />
<br />
<shift><ctrl>b = select current block<br />
<shift><ctrl>bb = select parent block (hold shift and control, press b two times)<br />
<shift><ctrl>bbb = select parent of parent block (etc.)<br />
<br />
<ctrl>z = undo<br />
<shift><ctrl>z = redo<br />
<br />
<ctrl>d = duplicate line<br />
<ctrl>y = duplicate line<br />
<ctrl>. = indent selection / indent current line<br />
<ctrl>, = unindent selection / unindent current line<br />
<shift><ctrl>c = toggle comment</div>OlivierSessinkhttps://bfwiki.tellefsen.net//index.php?title=Project_Roadmap&diff=2619Project Roadmap2014-12-18T09:59:24Z<p>OlivierSessink: </p>
<hr />
<div>The project roadmap outlines the future goals and milestones of the bluefish project.<br />
<br />
== 2.2.5 ==<br />
* faster syntax scanning after small changes to the text<br />
* fix for a bug in search and replace where nothing was replaced<br />
* much faster file pane with less memory usage, with various fixes and new features such as filenames from documents that are opened shown in bold<br />
* storing the active document and active line numbers in projects<br />
* much better javascript syntax highlighting and auto-completion, and adding jquery <br />
* syntax highlighting and auto-completion improvements for most supported languages<br />
* html code in php now defaults to html5<br />
* add appdata file<br />
* make the html plugin aware if the current syntax is html, html5 or xhtml<br />
* improve smart indenting<br />
* improve indenting in auto-completion code<br />
* replace jsmin with a version with a true open source licence <br />
* improve wrap text on right margin<br />
* fix split lines feature<br />
* fix several hard-to-reproduce crashes <br />
* better recovery after a kill or crash<br />
* improve paste special<br />
* improve bookmark functionality<br />
* OSX Native input methods now are supported (Japanese, Chinese, etc.)<br />
* Mac Retina displays are now supported.<br />
* OSX system hotkeys are working.<br />
* OSX Widget bindings on MacOSX are moved to Cmd+C|V|X|A and working<br />
* OSX opening files from the finder is now supported<br />
* OSX Mavericks support<br />
<br />
== 2.2.6 ==<br />
* fix critical bug (segfault) in filebrowser that could be triggered if the root was set as basedir<br />
* enable development define only if compiled from svn, not if compiled from tarball<br />
* various language file improvements, most of them in C, Javascript and CSS<br />
* fix a specific CSS-in-HTML-tag highlighting issue<br />
* Arabic translation added, Polish and Chinese translation updated<br />
* fix a corner case for a new document from a template that does not exist<br />
* the "open" submenu now opens SVG files from the filebrowser instead of inserting an image tag<br />
* fix segfault in filter code if the command does not exist<br />
* update cssmin and jsbeatify<br />
* fix a syntax scanning issue when replacing large chunks of text<br />
* fix the "Report bug" link<br />
* add a new "conditional" option to the language file that makes re-using certain blocks of language files easier<br />
* imporove error reporting in outputbox<br />
* OSX: fix filebrowser icons<br />
* OSX: fix "open file" dialog size<br />
* Windows: open in running process is finally supported on windows<br />
<br />
== 2.2.7 ==<br />
* fix rare crashes in the autocompletion, the filebrowser, the htmlbar plugin preferences, and in file-load-cancel<br />
* fix a rare case of broken syntax highlighting after multiple search/replace actions<br />
* better error/warning output when parsing language files<br />
* fix javascript regex syntax highlighting<br />
* improve loading of files with corrupt encoding (partially loading into read-only file)<br />
* improve project loading over sftp<br />
* HTML5 tags now supported in Generic HTML, PHP, CFML, etc.<br />
* fix UTF-16 loading/saving<br />
* improved css, html and pascal/delphi language file<br />
* improve autocompletion for html tags<br />
* OSX: changed the keys for tab switching such that they no longer confict with some keyboard layouts<br />
* OSX: improve behavior at shutdown<br />
* improve upload/download to ignore backup files<br />
* fix number of results in search and replace on files on disk<br />
* better fallback when loading files with a corrupt encoding<br />
* improve home/end keys on wrapped text<br />
<br />
== beyond 2.2.7 ==<br />
* make language options translatable<br />
* better error/warning output when parsing language files<br />
* remove synchronous calls from blocking code-paths in the filebrowser code<br />
* implement some sort of highlighting color theme so bluefish is also usable on dark themes without changing each and every color manually<br />
* better mimetype / syntax linking GUI, like the GUI proposed for win32<br />
* margin settings for printing<br />
* allow folding blocks in the print output<br />
<br />
* show color, when mouse over an color code (#000000)<br />
* option for snippet to open the color dialog<br />
* show search results in a list at left side<br />
* create a feature to change a tag to a different tag, and obviously also change the corresponding end-tag to that new value<br />
<br />
== beyond our planning horizon ==<br />
<br />
* clipboard history<br />
* undo redo browser<br />
<br />
some ideas:<br />
* completion of words in current document<br />
* storing undo/redo information in the project file</div>OlivierSessink