root/livinglogic.python.xist/src/ll/xist/converters.py @ 2520:b322c0ceba5d

Revision 2520:b322c0ceba5d, 7.8 KB (checked in by Walter Doerwald <walter@…>, 14 years ago)

Moved source files into src directory (to avoid import problems when
importing from the directory where setup.py is in).

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 maketarget(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="Target"><class>Target</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        The default is <lit>None</lit>.</par>
167        """
168        def __get__(self):
169            return self.states[-1].maketarget
170   
171        def __set__(self, maketarget):
172            self.states[-1].maketarget = maketarget
173   
174        def __delete__(self):
175            self.states[-1].maketarget = None
176
177    class makeproject(misc.propclass):
178        """
179        <par>If an &xist; conversion is done by an <pyref module="ll.make" class="XISTConvertAction"><class>XISTConvertAction</class></pyref>
180        this property will hold the <pyref module="ll.make" class="Project"><class>Project</class></pyref> object during that conversion.
181        If you're not using the <pyref module="ll.make"><module>make</module></pyref> module you can simply ignore this property.
182        """
183        def __get__(self):
184            maketarget = self.maketarget
185            if maketarget is None:
186                return None
187            else:
188                return maketarget.project
189
190    def push(self, node=None, root=None, mode=None, stage=None, target=None, lang=None, makeaction=None, maketarget=None):
191        self.lastnode = None
192        if node is None:
193            node = self.node
194        if root is None:
195            root = self.root
196        if mode is None:
197            mode = self.mode
198        if stage is None:
199            stage = self.stage
200        if target is None:
201            target = self.target
202        if lang is None:
203            lang = self.lang
204        if makeaction is None:
205            makeaction = self.makeaction
206        if maketarget is None:
207            maketarget = self.maketarget
208        self.states.append(ConverterState(node=node, root=root, mode=mode, stage=stage, target=target, lang=lang, makeaction=makeaction, maketarget=maketarget))
209
210    def pop(self):
211        if len(self.states)==1:
212            raise IndexError("can't pop last state")
213        state = self.states.pop()
214        self.lastnode = state.node
215        return state
216
217    def __getitem__(self, obj):
218        """
219        <par>Return a context object for <arg>obj</arg>, which should be an
220        <pyref module="ll.xist.xsc" class="Node"><class>Node</class></pyref> or
221        <pyref module="ll.xist.xsc" class="Namespace"><class>Namespace</class></pyref> subclass.
222        Each of these classes that defines its own
223        <pyref module="ll.xist.xsc" class="Element.Context"><class>Context</class></pyref>
224        class gets a unique instance of this class. This instance will be created
225        on the first access and the element can store information there that needs
226        to be available across calls to
227        <pyref module="ll.xist.xsc" class="Node" method="convert"><method>convert</method></pyref>.</par>
228        """
229        contextclass = obj.Context
230        # don't use setdefault(), as constructing the Context object might involve some overhead
231        try:
232            return self.contexts[contextclass]
233        except KeyError:
234            return self.contexts.setdefault(contextclass, contextclass())
235
236    # XPython support
237    def __enter__(self):
238        self.push(node=xsc.Frag())
239
240    # XPython support
241    def __leave__(self):
242        self.pop()
243        self.lastnode = self.lastnode.convert(self)
Note: See TracBrowser for help on using the browser.