⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pl_codegen.py

📁 用python写的ide开发环境,巨强大,不过需要wxpython的支持
💻 PY
📖 第 1 页 / 共 4 页
字号:
# pl_codegen.py: perl code generator# $Id: pl_codegen.py,v 1.41 2007/08/07 12:26:20 agriggio Exp $## Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net# License: MIT (see license.txt)# THIS PROGRAM COMES WITH NO WARRANTY## like all other perl parts, based on the pre-existing python generators#"""\How the code is generated: every time the end of an object is reached duringthe parsing of the xml tree, either the function 'add_object' or the function'add_class' is called: the latter when the object is a toplevel one, the formerwhen it is not. In the last case, 'add_object' calls the appropriate ``writer''function for the specific object, found in the 'obj_builders' dict. Suchfunction accepts one argument, the CodeObject representing the object forwhich the code has to be written, and returns 3 lists of strings, representingthe lines to add to the '__init__', '__set_properties' and '__do_layout'methods of the parent object."""import sys, os, os.pathimport common, configimport cStringIOfrom xml_parse import XmlParsingError# these two globals must be defined for every code generator modulelanguage = 'perl'writer = sys.modules[__name__] # the writer is the module itself# default extensions for generated files: a list of file extensionsdefault_extensions = ['pl','pm']"""\dictionary that maps the lines of code of a class to the name of such class:the lines are divided in 3 categories: '__init__', '__set_properties' and'__do_layout'"""classes = None"""dictionary of ``writers'' for the various objects"""obj_builders = {}"""\dictionary of ``property writer'' functions, used to set the properties of atoplevel object"""obj_properties = {}# random number used to be sure that the replaced tags in the sources are# the right ones (see SourceFileContent and add_class)nonce = None# lines common to all the generated files (use Wx [:everything], ...)header_lines = []# if True, generate a file for each custom classmultiple_files = False# if not None, it is the single source file to write intooutput_file = None# if not None, it is the directory inside which the output files are savedout_dir = Nonedef cn(class_name):    if class_name[:2] == 'wx':         return 'Wx::' + class_name[2:]    elif class_name[:4] == 'EVT_':        return 'Wx::' + class_name    else:        return class_nameclass ClassLines:    """\    Stores the lines of perl code for a custom class    """    def __init__(self):        self.init = [] # lines of code to insert in the __init__ method                       # (for children widgets)        self.parents_init = [] # lines of code to insert in the __init__ for                               # container widgets (panels, splitters, ...)        self.sizers_init = [] # lines related to sizer objects declarations        self.props = [] # lines to insert in the __set_properties method        self.layout = [] # lines to insert in the __do_layout method                self.dependencies = {} # names of the modules this class depends on        self.done = False # if True, the code for this class has already                          # been generated        self.event_handlers = [] # lines to bind events # end of class ClassLinesclass SourceFileContent:    """\    Keeps info about an existing file that has to be updated, to replace only    the lines inside a wxGlade block, an to keep the rest of the file as it was        WARNING: NOT YET COMPLETE    (always overwrites destination file, ALWAYS) -- crazyinsomniac    alb - the warning above shouldn't be true anymore... but we need testing...    """    def __init__(self, name=None, content=None, classes=None):        self.name = name # name of the file        self.content = content # content of the source file, if it existed                               # before this session of code generation        self.classes = classes # classes declared in the file        self.new_classes = [] # new classes to add to the file (they are                              # inserted BEFORE the old ones)        if classes is None: self.classes = {}        self.spaces = {} # indentation level for each class        self.event_handlers = {} # list of event handlers for each class        if self.content is None:            self.build_untouched_content()    def build_untouched_content(self):        """\        Builds a string with the contents of the file that must be left as is,        and replaces the wxGlade blocks with tags that in turn will be replaced        by the new wxGlade blocks                WARNING: NOT YET COMPLETE -- crazyinsomniac        alb - almost done :)        WARNING: There is *NO* support for here documents: if you put wxGlade        blocks inside a here document, you're likely going into troubles...        """        import re        class_name = None        new_classes_inserted = False        # regexp to match class declarations        #  package Foo; or package Foo::bar::baz   ;        #class_decl = re.compile(r'^\s*package\s+[a-zA-Z]\w*(::\w+)*\s*;\s*$')        # less precise regex, but working :-P        class_decl = re.compile(r'^\s*package\s+([a-zA-Z_][\w:]*)\s*;.*$')        # regexps to match wxGlade blocks        block_start = re.compile(r'^(\s*)#\s*begin\s+wxGlade:\s*'                                 '([a-zA-Z_][\w:]*?)::(\w+)\s*$')        block_end = re.compile(r'^\s*#\s*end\s+wxGlade\s*$')        pod_re = re.compile(r'^\s*=[A-Za-z_]+\w*.*$')        event_handler = re.compile(            r'#\s*wxGlade:\s*([\w:]+)::(\w+) <event_handler>\s*$')        inside_block = False        inside_pod = False        tmp_in = open(self.name)        out_lines = []        for line in tmp_in:            result = pod_re.match(line)            if result is not None:                inside_pod = True            if inside_pod:                out_lines.append(line)                if line.startswith('=cut'):                    inside_pod = False                continue                        result = class_decl.match(line)            if result is not None:                #print ">> found class %s" % result.group(1)                if class_name is None:                    # this is the first class declared in the file: insert the                    # new ones before this                    out_lines.append('#<%swxGlade insert new_classes>' %                                     nonce)                    new_classes_inserted = True                class_name = result.group(1)                self.classes[class_name] = 1 # add the found class to the list                                             # of classes of this module                out_lines.append(line)            elif not inside_block:                result = block_start.match(line)                if result is not None:                    # replace the lines inside a wxGlade block with a tag that                    # will be used later by add_class                    spaces = result.group(1)                    which_class = result.group(2)                    which_block = result.group(3)                    if which_class is None: which_class = class_name                    self.spaces[which_class] = spaces                    inside_block = True                    if class_name is None:                        out_lines.append('#<%swxGlade replace %s>' % \                                         (nonce, which_block))                    else:                        out_lines.append('#<%swxGlade replace %s %s>' % \                                         (nonce, which_class, which_block))                else:                    #- ALB 2004-12-05 ----------                    result = event_handler.match(line)                    if result is not None:                        which_handler = result.group(2)                        which_class = result.group(1)                        self.event_handlers.setdefault(                            which_class, {})[which_handler] = 1                    if class_name is not None and self.is_end_of_class(line):                        # add extra event handlers here...                        out_lines.append('#<%swxGlade event_handlers %s>'                                         % (nonce, class_name))                    #---------------------------                    out_lines.append(line)                    if line.lstrip().startswith('use Wx'):                        # add a tag to allow extra modules                        out_lines.append('#<%swxGlade extra_modules>\n'                                         % nonce)            else:                # ignore all the lines inside a wxGlade block                if block_end.match(line) is not None:                    inside_block = False        if not new_classes_inserted:            # if we are here, the previous ``version'' of the file did not            # contain any class, so we must add the new_classes tag at the            # end of the file            out_lines.append('#<%swxGlade insert new_classes>' % nonce)        tmp_in.close()        # set the ``persistent'' content of the file        self.content = "".join(out_lines)            def is_end_of_class(self, line):        return line.strip().startswith('# end of class ')# end of class SourceFileContent# if not None, it is an instance of SourceFileContent that keeps info about# the previous version of the source to generateprevious_source = None # if True, overwrite any previous version of the source file instead of# updating only the wxGlade blocks_overwrite = False# if True, enable gettext support_use_gettext = Falseimport re_quote_str_re = re.compile( r'\\(?![nrt])' )def quote_str(s):    """\    returns a quoted version of 's', suitable to insert in a perl source file    as a string object. Takes care also of gettext support    """    if not s: return '""'    s = _quote_str_re.sub(r'\\\\', s )    s = s.replace('"', r'\"')    s = s.replace('$', r'\$')    s = s.replace('@', r'\@')    if _use_gettext:        return '_T("' + s + '")'    else:        return '"' + s + '"'def quote_path(s):    """\    escapes all " and \ , thus making a path suitable to    insert in a perl source file    """ # " alb: comment needed to avoid emacs going insane with colorization..    s = s.replace('\\', '\\\\')    s = s.replace('"', r'\"')    s = s.replace('$', r'\$') # sigh    s = s.replace('@', r'\@')    return '"' + s + '"'def initialize(app_attrs):     """\    Writer initialization function.    - app_attrs: dict of attributes of the application. The following two                 are always present:           path: output path for the generated code (a file if multi_files is                 False, a dir otherwise)         option: if True, generate a separate file for each custom class    """    out_path = app_attrs['path']    multi_files = app_attrs['option']    global classes, header_lines, multiple_files, previous_source, nonce, \           _current_extra_modules, _use_gettext, _overwrite    import time, random##     # scan widgets.txt for widgets, load perl_codegen's##     _widgets_dir = os.path.join(common.wxglade_path, 'widgets')##     widgets_file = os.path.join(_widgets_dir, 'widgets.txt')##     if not os.path.isfile(widgets_file):##         print >> sys.stderr, "widgets file (%s) doesn't exist" % widgets_file##         return##     import sys##     sys.path.append(_widgets_dir)##     modules = open(widgets_file)##     for line in modules:##         module_name = line.strip()##         if not module_name or module_name.startswith('#'): continue##         module_name = module_name.split('#')[0].strip()##         try:##             m = __import__(##                 module_name + '.perl_codegen', {}, {}, ['initialize'])##             m.initialize()##         except (ImportError, AttributeError):##             print 'ERROR loading "%s"' % module_name##             import traceback;##             traceback.print_exc()## ##        else:## ##            print 'initialized perl generator for ', module_name##     modules.close()##     # ...then, the sizers##     import edit_sizers.perl_sizers_codegen##     edit_sizers.perl_sizers_codegen.initialize()      try:        _use_gettext = int(app_attrs['use_gettext'])    except (KeyError, ValueError):        _use_gettext = False    try: _overwrite = int(app_attrs['overwrite'])    except (KeyError, ValueError): _overwrite = False    # this is to be more sure to replace the right tags    nonce = '%s%s' % (str(time.time()).replace('.', ''),                      random.randrange(10**6, 10**7))    # ALB 2004-12-05    global for_version    try:        for_version = tuple([int(t) for t in                             app_attrs['for_version'].split('.')[:2]])    except (KeyError, ValueError):        if common.app_tree is not None:            for_version = common.app_tree.app.for_version        else:            for_version = (2, 4) # default...    classes = {}    _current_extra_modules = {}    header_lines = [        '# generated by wxGlade %s on %s%s\n' % \        (common.version, time.asctime(), common.generated_from()),         '# To get wxPerl visit http://wxPerl.sourceforge.net/\n\n',

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -