Kate/KWrite Syntax-Highlighting updaten

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
BlackJack

Dienstag 21. Juni 2005, 22:23

Das Syntax-Highlighting hängt bei vielen Editoren ja immer ein wenig der Python-Version hinterher. Bei kate/kwrite ist das auch so, darum habe ich ein kleines Skript geschrieben, das die Schlüsselworte und die eingebauten Namen aus der Python-Version ermittelt mit der es ausgeführt wird, und diese dann in die XML Datei einfügt, die kate/kwrite für das Syntax-Highlighting für Python benutzt.

Von der aktuellen Definitionsdatei wird eine Sicherheitskopie mit Datum und Uhrzeit im Namen angelegt.

Code: Alles auswählen

#!/usr/bin/env python
"""Script to update kate/kwrite syntax highlighting for Python.

The script updates the word lists for Python keywords and builtin names.  Both
informations are extracted from the running Python version, so the highlighting
matches exactly your version.  If you have different versions installed it
might be a good idea to use the latest one with this script.
"""
from __future__ import division
import os, sys, shutil, time, keyword
from elementtree import ElementTree

__author__ = "Marc 'BlackJack' Rintsch"
__version__ = '0.1.0'
__date__ = '$Date: 2005-06-21 15:48:17 +0200 (Tue, 21 Jun 2005) $'
__revision__ = '$Rev: 710 $'

__docformat__ = 'ReStructuredText'


class HighlightingListManipulator:
    """Wraps the "highlighting" element of the syntax definition.
    
    The syntax highlighting definition contains four word lists:
    
    prep
        Keywords for *preparing* the script like ``import``.
    
    statements
        The Python keywords without those in *prep*.
    
    builtinfuncs
        The builtin functions and constants without those in *specialvars*.
    
    specialvars
        Builtin names with special meaning, like ``self`` or ``None``.
    
    :invariant: *prep* not in *keywords* and
                *specialvars* not in *builtinfuncs*.

    :ivar highlighting_element: language highlighting element.
    :type highlighting_element: `ElementTree.Element`
    """
    def __init__(self, highlighting_element):
        self.highlighting_element = highlighting_element
    
    def _find_list_element(self, name):
        """Finds list element by name.
        
        :returns: first list element with a matching name attribute.
        :rtype: `ElementTree.Element`.
        
        :raises KeyError: if there is no list element with an appropriate
            name attribute.
        """
        for list_element in self.highlighting_element.findall('list'):
            if list_element.attrib['name'] == name:
                return list_element
        raise KeyError(name)
    
    def get_list_as_set(self, name):
        """Returns the content of the named list as set.
        
        :rtype: set([str])
        
        :raises KeyError: if there is no list element with an appropriate
            name attribute.
        """
        return set(item.text.strip()
                   for item in self._find_list_element(name).getchildren())
    
    def change_list(self, name, iterable):
        """Changes the contents of the list with `name` by the contents of
        the `iterable`.
        
        :raises KeyError: if there is no list element with an appropriate
            name attribute.
        """
        list_element = self._find_list_element(name)
        list_element.clear()
        list_element.set('name', name)
        list_element.text = list_element.tail = '\n'
        
        for item in sorted(iterable):
            item_element = ElementTree.SubElement(list_element, 'item')
            item_element.text = item
            item_element.tail = '\n'
    
    def _change_list(self, name, items, sub_name):
        """Changes contents of the list with given `name` with the contents of
        `items` minus the contents of the list with the name `sub_name`.
        """
        self.change_list(name, set(items) - self.get_list_as_set(sub_name))

    def change_keywords(self, keywords):
        """Changes the keywords, that is "statements" list element."""
        self._change_list('statements', keywords, 'prep')
    
    def change_builtins(self, builtins):
        """Changes the builtins, that is "builtinfuncs" list element."""
        self._change_list('builtinfuncs', builtins, 'specialvars')


def update(path, outfile=sys.stdout, encoding='utf-8'):
    """Updates the keywords and builtins in the file `path` and writes the
    updated XML document to `outfile`.
    
    :todo: Change `path` to `fileobj` to be more flexible.
    """
    # 
    # Read the XML document.
    # 
    python_highlight_def = ElementTree.parse(path)
    
    # 
    # Update the list elements.
    # 
    highlighting_element = python_highlight_def.find('highlighting')
    manipulator = HighlightingListManipulator(highlighting_element)
    manipulator.change_keywords(keyword.kwlist)
    manipulator.change_builtins(__builtins__.keys())
    
    # 
    # Write the XML document.
    # 
    header = (u'<?xml version="1.0" encoding="%s"?>\n'
              u'<!DOCTYPE language>\n' % encoding)
    outfile.write(header.encode(encoding))
    python_highlight_def.write(outfile, encoding)


def main():
    """Main function.  Makes backup of syntax highlighting definition file
    and updates the keywords and builtins.
    
    :todo: Try different paths.  At least the local and the global one as
        fallback if there is no local syntax highlighting definition.
    """
    path = os.path.expanduser('~/.kde/share/apps/katepart/syntax/python.xml')
    backup_path = path + '.' + time.strftime('%Y-%m-%d_%H:%M:%S')
    shutil.copy(path, backup_path)
    outfile = open(path, 'wb')
    update(backup_path, outfile)
    outfile.close()


if __name__ == '__main__':
    main()
Antworten