Пример #1
0
def wikiwordify(node, wcontext, wikiwords, on_unknown=on_unknown_camelword):
    """
	Given an ElementTree generated by wikklytext.buildXML, turn all
	wikiwords into links.
	
	node = ElementTree node (typically the rootnode from the parser).
	wcontext = WikContext
	wikiwords = Dict of wikiwords as:
		wikiwords[word] = URL
		
	on_unknown_camelword = callback when unknown camelwords are found.
		called as:
		   (text, needs_eval) = on_unknown(word)
		   
		Where: 
			text = replacement text.
			needs_eval = True/False if returned text is wikitext that needs
						 to be evaluated.

	Modifies the tree in place.
	"""
    from wikklytext.eval import eval_wiki_text
    from wikklytext.base import xmltrace, ElementList

    if node.tag == 'Text':
        raise Exception("<Text> cannot be at toplevel here.")

    # ignore <Text> nodes under these tags
    if node.tag in ('Link', 'Image', 'CreateAnchor'):
        return

    for i in range(len(node)):
        subnode = node[i]

        #print '<%s>' % subnode.tag
        # only <Text> nodes are eligible for wikiword substitution,
        # don't look in <TextCode>, <TextHTML>, etc.
        if subnode.tag == 'Text':
            #print "CONSIDER:",subnode.text
            wtext, needs_eval = wikiwordify_text(subnode.text or '', wikiwords,
                                                 on_unknown)
            if needs_eval:
                nodes = eval_wiki_text(wcontext, wtext)
            else:
                # saves a lot of time to only eval as needed
                nodes = [Text(wtext)]

            #print "GOT",xmltrace(nodes)
            # place all under a single ElementList
            elist = ElementList()
            for n in nodes:
                elist.append(n)

            #print "GOT",xmltrace(elist)

            # replace <Text> with <ElementList>
            node[i] = elist

        else:
            wikiwordify(subnode, wcontext, wikiwords, on_unknown)
Пример #2
0
 def getErrors(self):
     "Return current error list, in same format that 'addParserErrors' accepts."
     errors = self.rootnode.find('ErrorsList')
     if errors is None:
         return ElementList('ErrorsList')
     else:
         return errors
Пример #3
0
    def getInnerResult(self):
        """
		Returns 'inner' result, that is, the subnodes of the <Content> node,
		as an ElementList.
		"""
        outnode = ElementList()
        for node in self.rootnode.find('Content'):
            outnode.append(node)

        return outnode
Пример #4
0
def set(context, name, *elements):
    """
	|!Usage|{{{<<set name arg arg ... >>}}}|
	|!Description|Create a named variable containing the given wiki text. The text is evaluated (just as if it was inline) and stored. It can be retrieved later with {{{get()}}}.<br><br>//NOTE: Names beginning with {{{$}}} are reserved for system use.//|
	|!Example|{{{<<set TestVar "Some __text__ ''here''">>}}}|
	|!Result|//No return value.//|
	"""
    elements = eval_wiki_macro_args(context, elements)
    context.var_set(name.text, elements)

    return ElementList()  # no output
Пример #5
0
def if_full_mode(context, *elements):
    """
	|!Usage|{{{<<if_full_mode arg arg ...>>}}}|
	|!Description|If running in Full Mode, return wikified args, else return nothing.|
	|!Example|{{{<<if_full_mode "Hello ''Full Mode''">>}}}|
	|!Result|<<if_full_mode "Hello ''Full Mode''">>|
	"""
    if context.restricted_mode is False:
        return eval_wiki_macro_args(context, elements)
    else:
        return ElementList()
Пример #6
0
def py_add_path(context, path):
    """
	|!Usage|{{{<<py_add_path path>>}}}|
	|!Description|Add the given path to {{{sys.path}}}. This is useful when you want to use {{{include_code}}}, {{{include_pyfunc}}} or {{{include_pymod}}} on a module in an arbitrary location.|
	|!Example|{{{<<set TestVar "Some __text__ ''here''">>}}}|
	|!Result|//No return value.//|
	"""
    p = path.text
    p = os.path.abspath(p)
    #print "*** ADD PATH ***",p
    sys.path.insert(0, p)
    return ElementList()
Пример #7
0
def echo(context, *elements):
    """
	|!Usage|{{{<<echo arg arg ...>>}}}|
	|!Description|Echo back input arguments. Arguments are wikified just as if they were inline.|
	|!Example|{{{<<echo "//Hello//-" world '''-__macro__'''>>}}}|
	|!Result|<<echo "//Hello//-" world '''-__macro__'''>>|
	"""
    elements = eval_wiki_macro_args(context, elements)
    out = ElementList()
    for e in elements:
        out.append(e)

    return out
Пример #8
0
def echos(context, *elements):
    """
	|!Usage|{{{<<echos arg arg ...>>}}}|
	|!Description|Like {{{echo}}} but adds a space between arguments.|
	|!Example|{{{<<echos "AAA" BBB '''CCC'''>>}}}|
	|!Result|<<echos "AAA" BBB '''CCC'''>>|
	"""
    elements = eval_wiki_macro_args(context, elements)
    out = ElementList()
    for e in elements:
        out.append(e)
        out.append(Text(' '))

    return out
Пример #9
0
def eval_wiki_macro_args(wcontext, elements):
    """
	Evaluate all TextMacroArg nodes in elements, returning others untouched.

	Returns an Element with the evaluated elements as subnodes (you should
	not use the top Element, it is just a container. (An Element is returned
	because it acts both like a list and lets you do .find(), etc. as needed.)
	"""
    outnode = ElementList()
    for e in elements:
        if e.tag == 'TextMacroArg':
            for node in eval_wiki_text(wcontext, e.text):
                outnode.append(node)
        else:
            outnode.append(e)

    return outnode
Пример #10
0
def process_macro_result(wcontext, name, result):
    from wikklytext.eval import eval_wiki_text

    if iselement(result) and result.tag == 'ElementList':
        # already list-like, don't need to wrap
        pass

    # turn single values into list and handle below
    elif iselement(result) or isinstance(result, (unicode, str)):
        result = [result]

    elif isinstance(result, (list, tuple)):
        pass

    else:
        raise WikError("Calling <<%s>>\nMacros must return Elements or Unicode\nGot: %s, '%s'" % \
          (name, type(result), repr(result)))

    # now result can be handled as list/tuple - handle each element
    outnode = ElementList()
    for val in result:
        if iselement(val):
            outnode.append(val)  # leave Elements alone
        elif isinstance(val, unicode):  # parse Unicode -> Elements
            for e in eval_wiki_text(wcontext, val):
                outnode.append(e)
        elif isinstance(val, str):
            # note implicit unicode() conversion ... this is done for
            # convenience but macros should really return Unicode for
            # most robust code
            for e in eval_wiki_text(wcontext, unicode(val)):
                outnode.append(e)
        else:
            raise WikError("Calling <<%s>>\nMacros must return Elements or Unicode\nGot: %s, '%s'" % \
              (name, type(val), repr(val)))

    return outnode
Пример #11
0
def eval_wiki_elem(wcontext, elem):
    """
	Take a parsed tree, produced by e.g. parse_wiki_text(), and evaluate
	all <MacroCall> nodes (including any nodes found recursively).
	
	Returns evaluated node (which may be elem or may be a new node).
	"""
    import wikklytext.macro

    # evaluate my subnodes first in case they are needed as macro args
    # (there could be interior <MacroCalls> that need to be evaluated first)
    subnodes = [eval_wiki_elem(wcontext, e) for e in elem]

    # is elem a <MacroCall>?
    if elem.tag == 'MacroCall':
        # subnodes are (name, *args) -- the result of the macro call replaces all nodes
        # (including <MacroCall>)
        try:
            return wikklytext.macro.call_macro(wcontext, subnodes[0].text,
                                               subnodes[1:])
        except WikError, exc:
            # pass error to parser and continue
            wcontext.parser.error(exc.message, exc.looking_at, exc.trace)
            return ElementList()
Пример #12
0
        try:
            return wikklytext.macro.call_macro(wcontext, subnodes[0].text,
                                               subnodes[1:])
        except WikError, exc:
            # pass error to parser and continue
            wcontext.parser.error(exc.message, exc.looking_at, exc.trace)
            return ElementList()

    elif elem.tag == 'PyCode':
        assert (len(elem) == 1 and elem[0].tag == 'TextPyCode')
        try:
            wikklytext.macro.insert_pycode(wcontext, elem[0].text)
        except WikError, exc:
            self.wcontext.parser.error(exc.message, exc.looking_at, exc.trace)

        return ElementList()  # nothing to return

    else:
        # elem is a normal tag -- clone and set subnodes as children
        out = clonetop(elem)
        for e in subnodes:
            out.append(e)

        return out


def parse_wiki_text(wcontext, wikitext):
    """
	Parse wikitext, returning the result. This is the lowest-level parser.
	All other renderers (XML, HTML) are built on top of this.