root/livinglogic.python.xist/src/ll/xist/converters.py @ 2523:febb88d5af75

Revision 2523:febb88d5af75, 7.2 KB (checked in by Walter Doerwald <walter@…>, 14 years ago)

Fix regression from the make update: There's no longer any maketarget.

Line 
1#! /usr/bin/env python
2# -*- coding: iso-8859-1 -*-
3
4## Copyright 1999-2006 by LivingLogic AG, Bayreuth/Germany.
5## Copyright 1999-2006 by Walter Dörwald
6##
7## All Rights Reserved
8##
9## See xist/__init__.py for the license
10
11"""
12This modules contains the base class for the converter objects used in the call to the
13<pyref module="ll.xist.xsc" class="Node" method="convert"><method>convert</method></pyref> method.
14"""
15
16__version__ = "$Revision$".split()[1]
17# $Source$
18
19from ll import misc
20import xsc
21
22
23class ConverterState(object):
24    def __init__(self, node, root, mode, stage, target, lang, makeaction, makeproject):
25        self.node = node
26        self.root = root
27        self.mode = mode
28        self.stage = stage
29        if target is None:
30            from ll.xist.ns import html
31            target = html
32        self.target = target
33        self.lang = lang
34        self.makeaction = makeaction
35        self.makeproject = makeproject
36
37
38class Converter(object):
39    """
40    <par>An instance of this class is passed around in calls to the
41    <pyref module="ll.xist.xsc" class="Node" method="convert"><method>convert</method></pyref> method.
42    This instance can be used when some element needs to keep state across a nested convert call.
43    A typical example are nested chapter/subchapter elements with automatic numbering.
44    For an example see the element <pyref module="ll.xist.ns.doc" class="section"><class>ll.xist.ns.doc.section</class></pyref>.</par>
45    """
46    def __init__(self, node=None, root=None, mode=None, stage=None, target=None, lang=None, makeaction=None, makeproject=None):
47        """
48        <par>Create a <class>Converter</class>.</par>
49        <par>Arguments are used to initialize the <class>Converter</class> properties of the
50        same name.</par>
51        """
52        self.states = [ ConverterState(node=node, root=root, mode=mode, stage=stage, target=target, lang=lang, makeaction=makeaction, makeproject=makeproject)]
53        self.contexts = {}
54
55    class node(misc.propclass):
56        """
57        <par>The root node for which conversion has been called. This is automatically set by the
58        <pyref module="ll.xist.xsc" class="Node" method="conv"><method>conv</method></pyref> method.</par>
59        """
60        def __get__(self):
61            return self.states[-1].node
62   
63        def __set__(self, node):
64            self.states[-1].node = node
65   
66        def __delete__(self):
67            self.states[-1].node = None
68
69    class root(misc.propclass):
70        """
71        <par>The root &url; for the conversion. Resolving &url;s during the conversion process should be done
72        relative to <lit>root</lit>.</par>
73        """
74        def __get__(self):
75            return self.states[-1].root
76   
77        def __set__(self, root):
78            self.states[-1].root = root
79   
80        def __delete__(self):
81            self.states[-1].root = None
82
83    class mode(misc.propclass):
84        """
85        <par>The conversion mode. This corresponds directly to the mode in &xslt;.
86        The default is <lit>None</lit>.</par>
87        """
88        def __get__(self):
89            return self.states[-1].mode
90   
91        def __set__(self, mode):
92            self.states[-1].mode = mode
93   
94        def __delete__(self):
95            self.states[-1].mode = None
96
97    class stage(misc.propclass):
98        """
99        <par>If your conversion is done in multiple steps or stages you can use this property
100        to specify in which stage the conversion process currently is. The default is
101        <lit>"deliver"</lit>.</par>
102        """
103        def __get__(self):
104            if self.states[-1].stage is None:
105                return "deliver"
106            else:
107                return self.states[-1].stage
108   
109        def __set__(self, stage):
110            self.states[-1].stage = stage
111   
112        def __delete__(self):
113            self.states[-1].stage = None
114
115    class target(misc.propclass):
116        """
117        <par>Specifies the conversion target. This must be a
118        <pyref module="ll.xist.xsc" class="Namespace"><class>Namespace</class></pyref> subclass.</par>
119        """
120        def __get__(self):
121            if self.states[-1].target is None:
122                from ll.xist.ns import html
123                return html
124            else:
125                return self.states[-1].target
126   
127        def __set__(self, target):
128            self.states[-1].target = target
129   
130        def __delete__(self):
131            self.states[-1].target = None
132
133    class lang(misc.propclass):
134        """
135        <par>The target language. The default is <lit>None</lit>.</par>
136        """
137        def __get__(self):
138            return self.states[-1].lang
139   
140        def __set__(self, lang):
141            self.states[-1].lang = lang
142   
143        def __delete__(self):
144            self.states[-1].lang = None
145
146    class makeaction(misc.propclass):
147        """
148        <par>If an &xist; conversion is done by an <pyref module="ll.make" class="XISTConvertAction"><class>XISTConvertAction</class></pyref>
149        this property will hold the action object during that conversion. If you're not using the
150        <pyref module="ll.make"><module>make</module></pyref> module you can simply ignore this property. The default is <lit>None</lit>.</par>
151        """
152        def __get__(self):
153            return self.states[-1].makeaction
154   
155        def __set__(self, makeaction):
156            self.states[-1].makeaction = makeaction
157   
158        def __delete__(self):
159            self.states[-1].makeaction = None
160
161    class makeproject(misc.propclass):
162        """
163        <par>If an &xist; conversion is done by an <pyref module="ll.make" class="XISTConvertAction"><class>XISTConvertAction</class></pyref>
164        this property will hold the <pyref module="ll.make" class="Project"><class>Project</class></pyref> object during that conversion.
165        If you're not using the <pyref module="ll.make"><module>make</module></pyref> module you can simply ignore this property.
166        """
167        def __get__(self):
168            return self.states[-1].makeproject
169   
170        def __set__(self, makeproject):
171            self.states[-1].makeproject = makeproject
172   
173        def __delete__(self):
174            self.states[-1].makeproject = None
175
176    def push(self, node=None, root=None, mode=None, stage=None, target=None, lang=None, makeaction=None, makeproject=None):
177        self.lastnode = None
178        if node is None:
179            node = self.node
180        if root is None:
181            root = self.root
182        if mode is None:
183            mode = self.mode
184        if stage is None:
185            stage = self.stage
186        if target is None:
187            target = self.target
188        if lang is None:
189            lang = self.lang
190        if makeaction is None:
191            makeaction = self.makeaction
192        if makeproject is None:
193            makeproject = self.makeproject
194        self.states.append(ConverterState(node=node, root=root, mode=mode, stage=stage, target=target, lang=lang, makeaction=makeaction, makeproject=makeproject))
195
196    def pop(self):
197        if len(self.states)==1:
198            raise IndexError("can't pop last state")
199        state = self.states.pop()
200        self.lastnode = state.node
201        return state
202
203    def __getitem__(self, obj):
204        """
205        <par>Return a context object for <arg>obj</arg>, which should be an
206        <pyref module="ll.xist.xsc" class="Node"><class>Node</class></pyref> or
207        <pyref module="ll.xist.xsc" class="Namespace"><class>Namespace</class></pyref> subclass.
208        Each of these classes that defines its own
209        <pyref module="ll.xist.xsc" class="Element.Context"><class>Context</class></pyref>
210        class gets a unique instance of this class. This instance will be created
211        on the first access and the element can store information there that needs
212        to be available across calls to
213        <pyref module="ll.xist.xsc" class="Node" method="convert"><method>convert</method></pyref>.</par>
214        """
215        contextclass = obj.Context
216        # don't use setdefault(), as constructing the Context object might involve some overhead
217        try:
218            return self.contexts[contextclass]
219        except KeyError:
220            return self.contexts.setdefault(contextclass, contextclass())
221
222    # XPython support
223    def __enter__(self):
224        self.push(node=xsc.Frag())
225
226    # XPython support
227    def __leave__(self):
228        self.pop()
229        self.lastnode = self.lastnode.convert(self)
Note: See TracBrowser for help on using the browser.