I need a better explaination about how the formatter/text_python.py classes are supposed to work. It looks like it is a wrapper for the real formatter (like text_html), but which saves off a cached copy as a chunk of python code.

I seems though that this wrapper is affecting the order of the calls being made by the parser (such as wiki.py) and the real formatter. The result is that the real formatter is seeing nonsensible call sequences.

For example in 1.5.0 text_python's Formatter.heading() method:

def heading(self, on, depth, **kw):        
        if on:
            code = [
                self.__adjust_languge_state(),           # <---- TYPO !!!
                'request.write(%s.heading(%r, %r, **%r))' % (self.__formatter,
                                                             on, depth, kw),
                ]     
            return self.__insert_code(''.join(code))
        else:
            return self.formatter.heading(on, depth, **kw)

Now I've verified that even on a page with nothing but a = Hello = in it, that the wiki parser (once it gets to the content-div) is making two calls in the order,

  1. formatter.heading( 1, ....)
  2. formatter.heading( 0, ....)

But the text_html formatter is seeing this call first,

  1. formatter.heading( 0, ....)

Because the text_python is intercepting the first call.

Thus the html formatter is told to close a heading before it has opened one.

So far this may have just happened to have produced sloppy but renderable html by sheer luck. What's the black magic here? -- DeronMeranda 2006-01-19 10:27:27

The black magic is that we assume that the closing heading tag does not depend on the beginning tag. This is true for HTML but might be wrong for other formatters. If there is a real world example I would suggest to make the closing heading tag dynamic, too -- FlorianFesti 2006-01-22 16:54:46


So in essence there seem to be additional unspoken requirements for all formatters:

  1. A formatter should not assume that methods are called in any strict linear order.

    • No, thats wrong. Most formatters depend on linear non-stacked calls. Actually, this is just true for formatters that want to be cacheable. But the text_python.py formatter is incompatible to non-HTML markup anyway, so do not try that without "fixing" it.

  2. A formatter class should not assume that a single formatter instance/object will be used during the generation of a page.

    • Doesn't make sense IMHO. A page is only of one data type. Either it is output in PDF or HTML or foo or bar but ont in some starange mixture -- FlorianFesti 2006-01-22 16:54:46

These are far-reaching requirements that restrict the kind of formatters that can be created. For example I have been seriously thinking writing a PDF formatter. However the assumption that a header always consists of three disctinct pieces (a header-start, the header-text, and a header-end) and that all three components can be generated independently in any order is absurd. A PDF writer has to draw the entire header all at once. So me-thinks this may spoil my PDF plans. -- DeronMeranda 2006-01-19 17:57:33

If your formatter has to maintain a internal stack it is obviously impossible to cache parts of a page. Simply don't use cache then. -- FlorianFesti 2006-01-22 16:54:46

MoinMoin: DeronMeranda/DiscussPythonFormatter (last edited 2007-10-29 19:06:21 by localhost)