Kate XML Completion: Converting DTD to MetaDTD

Kate has this nifty little plugin called “XML Completion.” This plugin loads a Meta DTD file and uses this information for context sensitive completion. To use it, you first have to load it in the settings dialog, and then assign a Meta DTD through the XML menu:

In our example, we work on a Kate XML highlighting definition file and therefore loaded the file “language.dtd.xml” which is shipped with Kate. Having assigned a Meta DTD file, we now have these nice code hints:

Kate ships with several Meta DTD files, such as HTML4 (strict, loose) or XHTML 1.0 transitional, KConfigXT DTD, KPartsGUI or XSLT. While this is really cool, you may ask about arbitrary DTDs you may be using. Unfortunately, Kate only supports Meta DTD, so what now?

Installing dtdparser

Luckily, the tool dtdparser (on sourceforge) converts a DTD to Meta DTD. We first need to install dtdparse. Since openSUSE does not provide a package (what about other distros?), I downloaded SGML-DTDParse-2.00.zip, extracted it and ran (see README file)

perl Makefile.PL

Make sure there are no missing perl dependencies. I for instance had to install perl-Text-DelimMatch and perl-XML-DOM:

sudo zypper install perl-Text-DelimMatch perl-XML-DOM

Then continue with the build and install process (the result of make test should be PASS):

make test
sudo make install 

Now we successfully installed dtdparse on the system. So we are finally ready to convert DTDs.

Converting DTD to Meta DTD with dtdparser

Having installed dtdparser, it is as easy as calling

dtdparse file.dtd > file.dtd.xml

to convert a DTD to Meta DTD. The conversion should work out of the box. If you want, you can edit the generated .xml file, for instance the “title” attribute is always set to “?untitled?”. While this is not used by the XML Completion plugin (yet?), it’s still nicer to have it properly fixed.

Contributing Meta DTDs to Kate

Whenever you have a DTD that is of use also for other users, please send the generated Meta DTD to kwrite-devel@kde.org (our mailing list). Further, it would be really cool if someone added support to convert DTDs on the fly to Meta DTD, so the Kate XML Completion plugin would just work for DTDs as well. Any takers?

Call at Distribution Packagers

Please consider including dtdparser by default, as it seems to be a very useful too. Are there alternatives to convert DTD to Meta DTD?

Video Tutorials Learning C++ (in German)

I just stumbled over a really good tutorial on youtube that teaches C++ from the very beginning (in German). The tutorial is split into lots of small episodes, each about 10 to 15 minutes. The quality of these tutorials is very good in terms of video, voice and also contents. Subject is mostly “pure” C++ and later a bit of Qt is used, so it does not cover C nor lots of additional libraries. Still, if you want to understand the details, you might want to give it a try :-)

PS: The tutorials use Kate Part, just look at the code folding bar on the left. So the author is definitely doing something right :-p

Multiple Keyboard Layouts and Shortcuts

KDE has a very handy feature to switch keyboard layouts on the fly. This is for instance useful if you use the German keyboard layout by default, and the US layout for programming. To enable keyboard layout switching, go into System Settings > Input Devices (category Hardware) > Keyboard item > Layouts tab:

Here, ‘[x] Configure layouts‘ is checked, enabling the list view. I added the German keyboard layout, and then the English (US) layout. Notice also, that the shortcut is set to ‘Ctrl+Alt+K‘. Clicking apply, a tiny little indicator appears in the panel:

You now can quickly switch with Ctrl+Alt+K between the German and the US layout. Quite efficient, especially since the keyboard layout config page allows to switch the language on application basis.

Unchanged Keyboard Shortcuts

Switching the keyboard layout has one potential issue, though: The shortcuts remain unchanged. So if undo is mapped to Ctrl+z in the German layout, it is still mapped to Ctrl+z in the US layout. Note that by ‘z’ we refer to the hardware key on the keyboard. As a consequence, in the US layout, hitting the hardware key ‘y’ on the German keyboard inserts the character ‘z’, but the z in Ctrl+z is still on the hardware key ‘z’. This behavior may or may not be wanted.

Getting more into detail reveals that the order of the keyboard layouts in the first screen shot is of importance: If you first add the German ‘de‘ layout, and then the English ‘us‘ layout, then the shortcuts will always use the Germany keyboard layout, independent of what keyboard layout is chosen.

Reversely, if you first add the English ‘us’ layout, and then the German ‘de‘ layout, then the shortcuts will always use the English ‘us‘ keyboard layout.

So it seems that the order defines a priority, and the shortcuts always use the first entry in the list.

The correct solution to fix this would (in my humble opinion) be to add an option ‘[x] Shorcuts follow keyboard layout‘ or similar. But since this option does not exist, let’s do a quick hack to still get what we want here.

A Workaround

First we reset the shortcut in the settings of the keyboard layout options:

Click apply and close the dialog. Now, the shortcut ‘Ctrl+Alt+K‘ is unbound. Our idea is now to create a script that toggles the keyboard layout by calling setxkbmap with the appropriate parameters and bind this script via a global shortcut to ‘Ctrl+Alt+K‘.

To this end, we first have to create the script. So let’s first type `setxkbmap -query` in the console and check the output. For me, this results in:

$ setxkbmap -query
rules: evdev
model: pc101
layout: de,us
variant: nodeadkeys,

From this, we can follow that the current xkb layout is achieved with:

setxkbmap -model pc101 -layout de,us -variant nodeadkeys

Now, let’s switch the de,us to us,de and try the following:

setxkbmap -model pc101 -layout us,de -variant nodeadkeys

Notice, that the keyboard layout indicator in the panel switched to ‘us‘. Calling the first variant with de,us again, we get back to the German layout.

This discovery leads us to the following script switch-keyboard-layout.sh:


# query xkb map: us,de -> us is primary; de,us -> de is primary
dummy=`setxkbmap -query | grep us,de`

# return value 0: us,de; return value != 0, de,us
if [ $? -ne 0 ]; then
  # de is primary, now make us primary in list
  setxkbmap -model pc101 -layout us,de -variant nodeadkeys
  # us is primary, now make de primary in list
  setxkbmap -model pc101 -layout de,us -variant nodeadkeys

Save this script somewhere to switch-keyboard-layout.sh and make it executable with

chmod 755 switch-keyboard-layout.sh

Each time we execute this script, the keyboard layout is toggled.

Next, we go into System Settings again and navigate to Shortcuts and Gestures (Common Appearance and Behavior), there in the Custom Shortcuts we add a new Command/URL item named ‘SwitchKeyboardLayout’ as follows:

As a comment for this new item, we write ‘Switch Keyboard Layout‘, in the ‘Trigger‘ tab, bind the global shortcut to ‘Ctrl+Alt+K‘, and in the ‘Action‘ tab, choose the switch-keyboard-layout.sh script. Finally click Apply, and close the dialog.

Now, hitting Ctrl+Alt+K calls our script and correctly toggles the keyboard layout including the shortcuts.

Unfortunately, this approach does not support e.g. switching the keyboard layout on application basis as the switching policy of the Keyboard settings (first screen shot) allows. Still it works.

A final remark, though: For GTK applications this works out of the box. So is there any real reason why this is not the case for KDE / Qt applications? A real fix would be very much appreciated, I’d be also fine with an option. But not providing this feature at all is very thin ice…

Update: This issue was reported as KDE bug #197552 in 2009, and resolved as an upstream issue. However, it never was reported to Qt upstream. If I may say so, this is not how resolving bugs in KDE usually works. Grrr…

Scroll to top