예제 #1
0
 def mixer_handler(node, out):
     '''Handler function for nodes of type 'mixer'.'''
     if node.attr: a = node.attr
     else: a = {}
     if a.has_key('part'):
         if a['part'] == 'main':
             # write out the main part:
             writeoutdoc(main, out)
         elif a['part'] == 'title':
             # write out the title from the main part
             if title != None: writeoutdoc(title, out)
             else: writeoutdoc('Empty title!', out)
         else:  # handle other parts
             partfile = MIXERROOT + path + filename + '.' + a['part']
             if not (os.path.exists(partfile)):
                 if not (a.has_key('needed')) or a['needed'] != 'no':
                     err.write('Warning: Part "' + a['part'] +
                               '" not found for ' + 'document "' + path +
                               filename + '.mixer"!\n')
             else:
                 e = maxml.parse_file_for_rewrite(partfile)
                 writeoutdoc(e.subs, out)
     elif a.has_key('var'):
         if a['var'] == 'source':
             out.write('<a href="' + path + filename +
                       '.mixer">MIXERFILE</a>')
         elif a['var'] == 'timestamp':
             out.write(
                 time.ctime(
                     os.stat(MIXERROOT + path + filename +
                             '.mixer').st_mtime))
         elif config.has_key(a['var']):
             out.write(config[a['var']])
         else:
             err.write('Warning: Variable ' + a['var'] + ' undefined!\n')
     elif a.has_key('parsevar'):
         if config.has_key(a['parsevar']):
             t = '<?xml version="1.0" encoding="utf-8"?>\n<mixer>\n'+\
                 config[a['parsevar']] + \
                 '</mixer>'
             e = maxml.parse_string_for_rewrite(t)
             writeoutdoc(e.subs, out)
         else:
             err.write('Warning: Variable ' + a['parsevar'] +
                       ' undefined!\n')
     elif a.has_key('func'):
         if not (funcs.__dict__.has_key(a['func'])):
             err.write('Warning: Function "' + a['func'] +
                       '" not found for ' + 'document "' + path + filename +
                       '.mixer"!\n')
         else:
             writeoutdoc(
                 funcs.__dict__[a['func']](MIXERROOT, path, filename, main,
                                           node), out)
     elif a.has_key('person') and a.has_key('data'):
         if not (people.has_key(a['person'])):
             err.write('Warning: Person unknown: "' + a['person'] + '"!\n')
         elif not (people[a['person']].has_key(a['data'])):
             err.write('Warning: Data "' + a['data'] + '" for person "' +
                       a['person'] + '" not in database!\n')
         else:
             writeoutdoc(people[a['person']][a['data']], out)
     elif len(a.keys()) == 1:  # the short form for functions:
         f = a.keys()[0]
         if not (funcs.__dict__.has_key(f)):
             err.write('Warning: Function "' + f + '" not found for ' +
                       'document "' + path + filename + '.mixer"!\n')
         else:
             writeoutdoc(
                 funcs.__dict__[f](MIXERROOT, path, filename, main, node),
                 out)
     return 1
예제 #2
0
파일: mixer.py 프로젝트: gap-system/Mixer
 def mixer_handler(node,out):
     '''Handler function for nodes of type 'mixer'.'''
     if node.attr: a = node.attr
     else:         a = {}
     if a.has_key('part'):
         if a['part'] == 'main':
             # write out the main part:
             writeoutdoc(main,out)
         elif a['part'] == 'title':
             # write out the title from the main part
             if title != None: writeoutdoc(title,out)
             else:             writeoutdoc('Empty title!',out)
         else:  # handle other parts
             partfile = MIXERROOT+path+filename+'.'+a['part']
             if not(os.path.exists(partfile)):
                 if not(a.has_key('needed')) or a['needed'] != 'no':
                   err.write('Warning: Part "'+a['part']+'" not found for '+
                             'document "'+path+filename+'.mixer"!\n')
             else:
                 e = maxml.parse_file_for_rewrite(partfile)
                 writeoutdoc(e.subs,out)
     elif a.has_key('var'):
         if a['var'] == 'source':
             out.write('<a href="'+path+filename+'.mixer">MIXERFILE</a>')
         elif a['var'] == 'timestamp':
             out.write(time.ctime(
                       os.stat(MIXERROOT+path+filename+'.mixer').st_mtime))
         elif config.has_key(a['var']):
             out.write(config[a['var']])
         else:
             err.write('Warning: Variable '+a['var']+' undefined!\n')
     elif a.has_key('parsevar'):
         if config.has_key(a['parsevar']):
             t = '<?xml version="1.0" encoding="ISO-8859-1"?>\n<mixer>\n'+\
                 config[a['parsevar']] + \
                 '</mixer>'
             e = maxml.parse_string_for_rewrite(t)
             writeoutdoc(e.subs,out)
         else:
             err.write('Warning: Variable '+a['parsevar']+' undefined!\n')
     elif a.has_key('func'):
         if not(funcs.__dict__.has_key(a['func'])):
             err.write('Warning: Function "'+a['func']+'" not found for '+
                       'document "'+path+filename+'.mixer"!\n')
         else:
             writeoutdoc(funcs.__dict__[a['func']](MIXERROOT,path,filename,
                                                   main,node), out)
     elif a.has_key('person') and a.has_key('data'):
         if not(people.has_key(a['person'])):
             err.write('Warning: Person unknown: "'+a['person']+'"!\n')
         elif not(people[a['person']].has_key(a['data'])):
             err.write('Warning: Data "'+a['data']+'" for person "'+
                       a['person']+'" not in database!\n')
         else:
             writeoutdoc(people[a['person']][a['data']],out)
     elif len(a.keys()) == 1:    # the short form for functions:
         f = a.keys()[0]
         if not(funcs.__dict__.has_key(f)):
             err.write('Warning: Function "'+f+'" not found for '+
                       'document "'+path+filename+'.mixer"!\n')
         else:
             writeoutdoc(funcs.__dict__[f](MIXERROOT,path,filename,
                                           main,node),out)
     return 1
예제 #3
0
def workerfunc(path, filename):
    '''This function is called for all files ending in '.mixer' in the
    mixer hierarchy. 'path' is a path to the directory (relative from 
    the MIXERROOT and filename is the name of the file (without '.mixer' at
    the end. So we have to make MIXERROOT+path+filename+".html" from
    MIXERROOT+path+filename+'.mixer' plus things in MIXERLIB and files like
    MIXERROOT+path+filename+'.something'.'''

    currentlang = ''  # this means "unset"

    def make_link_relative(l):
        '''Takes the link in l and
        leaves it     if it contains a colon,
        leaves it     if it does not start with a slash and
        makes it into a relative one  if it starts with a slash. In the
        last case it will point to the position which is specified by
        l relative from the MIXERROOT.'''
        if l.find(':') >= 0 or (len(l) > 0 and l[0] != '/'):
            return l
        return ('../' * path.count('/')) + l[1:]

    # in the following dictionary we collect handlers for special nodes:
    specialnodehandlers = {}

    def mixer_handler(node, out):
        '''Handler function for nodes of type 'mixer'.'''
        if node.attr: a = node.attr
        else: a = {}
        if a.has_key('part'):
            if a['part'] == 'main':
                # write out the main part:
                writeoutdoc(main, out)
            elif a['part'] == 'title':
                # write out the title from the main part
                if title != None: writeoutdoc(title, out)
                else: writeoutdoc('Empty title!', out)
            else:  # handle other parts
                partfile = MIXERROOT + path + filename + '.' + a['part']
                if not (os.path.exists(partfile)):
                    if not (a.has_key('needed')) or a['needed'] != 'no':
                        err.write('Warning: Part "' + a['part'] +
                                  '" not found for ' + 'document "' + path +
                                  filename + '.mixer"!\n')
                else:
                    e = maxml.parse_file_for_rewrite(partfile)
                    writeoutdoc(e.subs, out)
        elif a.has_key('var'):
            if a['var'] == 'source':
                out.write('<a href="' + path + filename +
                          '.mixer">MIXERFILE</a>')
            elif a['var'] == 'timestamp':
                out.write(
                    time.ctime(
                        os.stat(MIXERROOT + path + filename +
                                '.mixer').st_mtime))
            elif config.has_key(a['var']):
                out.write(config[a['var']])
            else:
                err.write('Warning: Variable ' + a['var'] + ' undefined!\n')
        elif a.has_key('parsevar'):
            if config.has_key(a['parsevar']):
                t = '<?xml version="1.0" encoding="utf-8"?>\n<mixer>\n'+\
                    config[a['parsevar']] + \
                    '</mixer>'
                e = maxml.parse_string_for_rewrite(t)
                writeoutdoc(e.subs, out)
            else:
                err.write('Warning: Variable ' + a['parsevar'] +
                          ' undefined!\n')
        elif a.has_key('func'):
            if not (funcs.__dict__.has_key(a['func'])):
                err.write('Warning: Function "' + a['func'] +
                          '" not found for ' + 'document "' + path + filename +
                          '.mixer"!\n')
            else:
                writeoutdoc(
                    funcs.__dict__[a['func']](MIXERROOT, path, filename, main,
                                              node), out)
        elif a.has_key('person') and a.has_key('data'):
            if not (people.has_key(a['person'])):
                err.write('Warning: Person unknown: "' + a['person'] + '"!\n')
            elif not (people[a['person']].has_key(a['data'])):
                err.write('Warning: Data "' + a['data'] + '" for person "' +
                          a['person'] + '" not in database!\n')
            else:
                writeoutdoc(people[a['person']][a['data']], out)
        elif len(a.keys()) == 1:  # the short form for functions:
            f = a.keys()[0]
            if not (funcs.__dict__.has_key(f)):
                err.write('Warning: Function "' + f + '" not found for ' +
                          'document "' + path + filename + '.mixer"!\n')
            else:
                writeoutdoc(
                    funcs.__dict__[f](MIXERROOT, path, filename, main, node),
                    out)
        return 1

    specialnodehandlers['mixer'] = mixer_handler

    def comment_handler(node, out):
        '''Handler function for comment nodes.'''
        out.write('<!--')
        writeoutdoc(node.subs, out)
        out.write('-->')
        return 1

    specialnodehandlers['<!--'] = comment_handler

    def pi_handler(node, out):
        '''Handler function for processing instruction nodes.'''
        out.write('<?' + node.attr['name'] + ' ')
        writeoutdoc(node.subs, out)
        out.write('?>')
        return 1

    specialnodehandlers['<?'] = pi_handler

    def cdata_handler(node, out):
        '''Handler function for CDATA section nodes.'''
        #out.write('<![CDATA[')
        out.write(node.subs[0])
        #out.write(']]>')
        return 1

    specialnodehandlers['<![CDATA['] = cdata_handler

    def link_handler(node, out):
        '''Handler function for link nodes.'''
        # handle stylesheet declaration in link element:
        if node.attr != None and node.attr.has_key('rel') and \
           node.attr['rel'] == 'StyleSheet':
            # Make a copy:
            if attr.has_key('oldstyle'):
                newhref = make_link_relative(attr['oldstyle'])
            else:
                newhref = make_link_relative(node.attr['href'])
            out.write('<link href="' + newhref + '"')
            for k in node.attr.keys():
                if k != 'href':
                    out.write(' ' + k + '="' + node.attr[k] + '"')
            out.write(' />')
            return 1
        return 0

    specialnodehandlers['link'] = link_handler

    def style_handler(node, out):
        '''Handler function for style nodes.'''
        # handle stylesheet declaration in style element:
        if node.attr != None and node.attr.has_key('type') and \
           node.attr['type'] == 'text/css':
            if attr.has_key('style'):
                return '@import url(' + make_link_relative(
                    attr['style']) + ');'
            # handle rewriting of the default link in here:
            if node.subs[0][:12] == '@import url(' and \
               node.subs[0][-2:] == ');':
                return '@import url(' + make_link_relative(
                    node.subs[0][12:-2]) + ');'
        return 0

    specialnodehandlers['style'] = style_handler

    def title_handler(node, out):
        '''Handler function for style nodes.'''
        if title != None: return title
        return 0

    specialnodehandlers['title'] = title_handler

    def writeoutdoc(node, out):
        '''This function really writes out a document recursively. 
        node is a tuple describing one node of an xml tree or a string
        or a list of such things.
        This function uses the local variables 'main', 'attr', 'path' and
        'filename' from the surrounding function. 'out' is a file object
        where the output is written to.'''
        # First handle different data types:
        if node == None: return
        elif type(node) == types.ListType:
            for s in node:
                writeoutdoc(s, out)
            return
        elif type(node) == types.StringType:
            out.write(node)
            return
        elif type(node) != types.InstanceType:
            err.write("Error: Strange object in tree:" + str(node) + "\n")
            sys.exit(9)

        # now we know it is a real node, is there special action necessary?
        replacement = 0
        if specialnodehandlers.has_key(node.type):
            replacement = specialnodehandlers[node.type](node, out)
            if replacement == 1: return

        # now write it out:

        # first adjust a possible 'href' attribute in case of an internal link:
        if node.attr != None and node.attr.has_key('href'):
            href = node.attr['href']
            done = 0
            while not (done):
                done = 1
                ps = href.find('{{')
                pe = href.find('}}')
                if ps >= 0 and pe >= 0 and pe > ps:
                    varname = href[ps + 2:pe]
                    if config.has_key(varname):
                        href = href[:ps] + config[varname] + href[pe + 2:]
                        done = 0  # possibly more to replace
                    else:
                        err.write("Warning: Variable undefined: " + varname +
                                  "\n")
            # we make it relative:
            href = make_link_relative(href)

        # now adjust a possible 'src' attribute in case of an internal link:
        if node.attr != None and node.attr.has_key('src'):
            src = node.attr['src']
            done = 0
            while not (done):
                done = 1
                ps = src.find('{{')
                pe = src.find('}}')
                if ps >= 0 and pe >= 0 and pe > ps:
                    varname = src[ps + 2:pe]
                    if config.has_key(varname):
                        src = src[:ps] + config[varname] + src[pe + 2:]
                        done = 0  # possibly more to replace
                    else:
                        err.write("Warning: Variable undefined: " + varname +
                                  "\n")
            # we make it relative:
            src = make_link_relative(src)

        # throw it away if language is set and not the current one:
        if currentlang != '' and node.attr != None:
            if node.attr.has_key('xml:lang'): l = node.attr['xml:lang']
            elif node.attr.has_key('lang'): l = node.attr['lang']
            else: l = ''
            if l != '' and currentlang != l: return

        # now write out the node:
        out.write('<' + node.type)
        if node.attr != None:
            for k in node.attr:
                if k == 'href':
                    out.write(' href="' + href + '"')
                elif k == 'src':
                    out.write(' src="' + src + '"')
                else:
                    out.write(' ' + k + '="' + node.attr[k] + '"')
        if replacement == 0 and node.subs == None:  # is it empty?
            out.write(' />')
        else:
            out.write('>')  # no, at least not explicitly empty
            if replacement != 0:
                writeoutdoc(replacement, out)
            else:
                writeoutdoc(node.subs, out)  # this can handle a list
            out.write('</' + node.type + '>')

        # end of function 'writeoutdoc'

    source = MIXERROOT + path + filename + '.mixer'
    target = MIXERROOT + path + filename + '.html'
    if force or not(os.path.exists(target)) or \
       (os.stat(source).st_mtime > os.stat(target).st_mtime):
        # we have to do something:
        main = maxml.parse_file_for_rewrite(source)
        if main.type != 'mixer':
            err.write("Error: No <mixer> element!\n")
            sys.exit(8)
        attr = main.attr
        main = main.subs
        i = 0
        while i < len(main) and \
              (type(main[i]) != types.InstanceType or
               main[i].type != 'mixertitle'):
            i += 1
        if i < len(main):
            title = main[i].subs
            del main[i]
        else:
            title = None

        attr.setdefault('template', 'default.tmpl')
        template = attr['template']
        tmpl = search_up(MIXERROOT, path, template)
        if tmpl == None:
            err.write("Error: Unknown template file: " + template + "\n")
            sys.exit(9)
        template = maxml.parse_file_for_rewrite(MIXERROOT + tmpl + template)
        out = file(target, "w")
        out.write('<?xml version="1.0" encoding="utf-8"?>\n\n')
        if not (nodoctype):
            out.write('''<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n\n''')
        writeoutdoc(template, out)
        out.write('\n<!-- Created by mixer. -->\n')
        out.close()
        if quiet == 1:
            print "Updated", MIXERROOT + path + filename + ".html"
    else:
        if quiet == 0: print "Nothing to be done."
예제 #4
0
파일: mixer.py 프로젝트: gap-system/Mixer
def workerfunc(path,filename):
    '''This function is called for all files ending in '.mixer' in the
    mixer hierarchy. 'path' is a path to the directory (relative from 
    the MIXERROOT and filename is the name of the file (without '.mixer' at
    the end. So we have to make MIXERROOT+path+filename+".html" from
    MIXERROOT+path+filename+'.mixer' plus things in MIXERLIB and files like
    MIXERROOT+path+filename+'.something'.'''

    currentlang = ''   # this means "unset"

    def make_link_relative(l):
        '''Takes the link in l and
        leaves it     if it contains a colon,
        leaves it     if it does not start with a slash and
        makes it into a relative one  if it starts with a slash. In the
        last case it will point to the position which is specified by
        l relative from the MIXERROOT.'''
        if l.find(':') >= 0 or (len(l) > 0 and l[0] != '/'):
            return l
        return ('../' * path.count('/'))+l[1:]

    # in the following dictionary we collect handlers for special nodes:
    specialnodehandlers = {}

    def mixer_handler(node,out):
        '''Handler function for nodes of type 'mixer'.'''
        if node.attr: a = node.attr
        else:         a = {}
        if a.has_key('part'):
            if a['part'] == 'main':
                # write out the main part:
                writeoutdoc(main,out)
            elif a['part'] == 'title':
                # write out the title from the main part
                if title != None: writeoutdoc(title,out)
                else:             writeoutdoc('Empty title!',out)
            else:  # handle other parts
                partfile = MIXERROOT+path+filename+'.'+a['part']
                if not(os.path.exists(partfile)):
                    if not(a.has_key('needed')) or a['needed'] != 'no':
                      err.write('Warning: Part "'+a['part']+'" not found for '+
                                'document "'+path+filename+'.mixer"!\n')
                else:
                    e = maxml.parse_file_for_rewrite(partfile)
                    writeoutdoc(e.subs,out)
        elif a.has_key('var'):
            if a['var'] == 'source':
                out.write('<a href="'+path+filename+'.mixer">MIXERFILE</a>')
            elif a['var'] == 'timestamp':
                out.write(time.ctime(
                          os.stat(MIXERROOT+path+filename+'.mixer').st_mtime))
            elif config.has_key(a['var']):
                out.write(config[a['var']])
            else:
                err.write('Warning: Variable '+a['var']+' undefined!\n')
        elif a.has_key('parsevar'):
            if config.has_key(a['parsevar']):
                t = '<?xml version="1.0" encoding="ISO-8859-1"?>\n<mixer>\n'+\
                    config[a['parsevar']] + \
                    '</mixer>'
                e = maxml.parse_string_for_rewrite(t)
                writeoutdoc(e.subs,out)
            else:
                err.write('Warning: Variable '+a['parsevar']+' undefined!\n')
        elif a.has_key('func'):
            if not(funcs.__dict__.has_key(a['func'])):
                err.write('Warning: Function "'+a['func']+'" not found for '+
                          'document "'+path+filename+'.mixer"!\n')
            else:
                writeoutdoc(funcs.__dict__[a['func']](MIXERROOT,path,filename,
                                                      main,node), out)
        elif a.has_key('person') and a.has_key('data'):
            if not(people.has_key(a['person'])):
                err.write('Warning: Person unknown: "'+a['person']+'"!\n')
            elif not(people[a['person']].has_key(a['data'])):
                err.write('Warning: Data "'+a['data']+'" for person "'+
                          a['person']+'" not in database!\n')
            else:
                writeoutdoc(people[a['person']][a['data']],out)
        elif len(a.keys()) == 1:    # the short form for functions:
            f = a.keys()[0]
            if not(funcs.__dict__.has_key(f)):
                err.write('Warning: Function "'+f+'" not found for '+
                          'document "'+path+filename+'.mixer"!\n')
            else:
                writeoutdoc(funcs.__dict__[f](MIXERROOT,path,filename,
                                              main,node),out)
        return 1
    specialnodehandlers['mixer'] = mixer_handler

    def comment_handler(node,out):
        '''Handler function for comment nodes.'''
        out.write('<!--')
        writeoutdoc(node.subs,out)
        out.write('-->')
        return 1
    specialnodehandlers['<!--'] = comment_handler

    def pi_handler(node,out):
        '''Handler function for processing instruction nodes.'''
        out.write('<?'+node.attr['name']+' ')
        writeoutdoc(node.subs,out)
        out.write('?>')
        return 1
    specialnodehandlers['<?'] = pi_handler

    def cdata_handler(node,out):
        '''Handler function for CDATA section nodes.'''
        #out.write('<![CDATA[')
        out.write(node.subs[0])
        #out.write(']]>')
        return 1
    specialnodehandlers['<![CDATA['] = cdata_handler

    def link_handler(node,out):
        '''Handler function for link nodes.'''
        # handle stylesheet declaration in link element:
        if node.attr != None and node.attr.has_key('rel') and \
           node.attr['rel'] == 'StyleSheet':
            # Make a copy:
            if attr.has_key('oldstyle'): 
                newhref = make_link_relative(attr['oldstyle'])
            else:
                newhref = make_link_relative(node.attr['href'])
            out.write('<link href="'+newhref+'"')
            for k in node.attr.keys(): 
                 if k != 'href':
                     out.write(' '+k+'="'+node.attr[k]+'"')
            out.write(' />')
            return 1
        return 0
    specialnodehandlers['link'] = link_handler

    def style_handler(node,out):
        '''Handler function for style nodes.'''
        # handle stylesheet declaration in style element:
        if node.attr != None and node.attr.has_key('type') and \
           node.attr['type'] == 'text/css':
            if attr.has_key('style'):
                return '@import url('+make_link_relative(attr['style'])+');'
            # handle rewriting of the default link in here:
            if node.subs[0][:12] == '@import url(' and \
               node.subs[0][-2:] == ');':
              return '@import url('+make_link_relative(node.subs[0][12:-2])+');'
        return 0
    specialnodehandlers['style'] = style_handler

    def title_handler(node,out):
        '''Handler function for style nodes.'''
        if title != None: return title
        return 0
    specialnodehandlers['title'] = title_handler

    def writeoutdoc(node,out):
        '''This function really writes out a document recursively. 
        node is a tuple describing one node of an xml tree or a string
        or a list of such things.
        This function uses the local variables 'main', 'attr', 'path' and
        'filename' from the surrounding function. 'out' is a file object
        where the output is written to.'''
        # First handle different data types:
        if node == None: return
        elif type(node) == types.ListType:
            for s in node: writeoutdoc(s,out)
            return
        elif type(node) == types.StringType:
            out.write(node)
            return
        elif type(node) != types.InstanceType:
            err.write("Error: Strange object in tree:"+str(node)+"\n")
            sys.exit(9)

        # now we know it is a real node, is there special action necessary?
        replacement = 0
        if specialnodehandlers.has_key(node.type):
            replacement = specialnodehandlers[node.type](node,out)
            if replacement == 1: return

        # now write it out:

        # first adjust a possible 'href' attribute in case of an internal link:
        if node.attr != None and node.attr.has_key('href'):
            href = node.attr['href']
            done = 0
            while not(done):
                done = 1
                ps = href.find('{{')
                pe = href.find('}}')
                if ps >= 0 and pe >= 0 and pe > ps:
                    varname = href[ps+2:pe]
                    if config.has_key(varname):
                        href = href[:ps] + config[varname] + href[pe+2:]
                        done = 0  # possibly more to replace
                    else:
                        err.write("Warning: Variable undefined: "+varname+"\n")
            # we make it relative:
            href = make_link_relative(href)

        # now adjust a possible 'src' attribute in case of an internal link:
        if node.attr != None and node.attr.has_key('src'):
            src = node.attr['src']
            done = 0
            while not(done):
                done = 1
                ps = src.find('{{')
                pe = src.find('}}')
                if ps >= 0 and pe >= 0 and pe > ps:
                    varname = src[ps+2:pe]
                    if config.has_key(varname):
                        src = src[:ps] + config[varname] + src[pe+2:]
                        done = 0  # possibly more to replace
                    else:
                        err.write("Warning: Variable undefined: "+varname+"\n")
            # we make it relative:
            src = make_link_relative(src)

        # throw it away if language is set and not the current one:
        if currentlang != '' and node.attr != None:
            if node.attr.has_key('xml:lang'): l = node.attr['xml:lang']
            elif node.attr.has_key('lang'):   l = node.attr['lang']
            else: l = ''
            if l != '' and currentlang != l: return

        # now write out the node:
        out.write('<'+node.type)
        if node.attr != None:
            for k in node.attr: 
                if k == 'href':
                    out.write(' href="'+href+'"')
		elif k == 'src':
                    out.write(' src="'+src+'"')
                else:
                    out.write(' '+k+'="'+node.attr[k]+'"')
        if replacement == 0 and node.subs == None:   # is it empty?
            out.write(' />')
        else:
            out.write('>')    # no, at least not explicitly empty
            if replacement != 0:
                writeoutdoc(replacement,out)
            else:
                writeoutdoc(node.subs,out)   # this can handle a list
            out.write('</'+node.type+'>')

        # end of function 'writeoutdoc'

    source = MIXERROOT+path+filename+'.mixer'
    target = MIXERROOT+path+filename+'.html'
    if force or not(os.path.exists(target)) or \
       (os.stat(source).st_mtime > os.stat(target).st_mtime):
        # we have to do something:
        main = maxml.parse_file_for_rewrite(source)
        if main.type != 'mixer': 
            err.write("Error: No <mixer> element!\n")
            sys.exit(8)
        attr = main.attr
        main = main.subs
        i = 0
        while i < len(main) and \
              (type(main[i]) != types.InstanceType or
               main[i].type != 'mixertitle'): i += 1
        if i < len(main): 
            title = main[i].subs
            del main[i]
        else:
            title = None

        attr.setdefault('template','default.tmpl')
        template = attr['template']
        tmpl = search_up(MIXERROOT,path,template)
        if tmpl == None:
            err.write("Error: Unknown template file: "+template+"\n")
            sys.exit(9)
        template = maxml.parse_file_for_rewrite(MIXERROOT+tmpl+template)
        out = file(target,"w")
        out.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n\n')
        if not(nodoctype):
            out.write('''<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n\n''')
        writeoutdoc(template,out)
        out.write('\n<!-- Created by mixer. -->\n')
        out.close()
        if quiet == 1:
            print "Updated",MIXERROOT+path+filename+".html"
    else:
        if quiet == 0: print "Nothing to be done."