root/livinglogic.python.xist/MIGRATION.xml @ 2590:7b6bba35f3a0

Revision 2590:7b6bba35f3a0, 23.2 KB (checked in by Walter Doerwald <walter@…>, 13 years ago)

htmlspecials.pixel() now no longer uses colored pixels, instead color is
done via CSS. The URL for the one remaining transparent pixel can now be
specified via src (either as an XML attribute or via the converter context).

Rename attrs methods with() and without() to withnames() and withoutnames()
(for Python 2.5 compatibility).

Use elinks instead of w3m for asText() and move/rename this method to a
function ll.xist.ns.html.astext().

Try to make XIST independent from PyXML (however PyXML is still required
for parsing via expat and for dtd2xsc.py (because this requires xmlproc)).

Remove the long dperecated method withSep().

Use Py_ssize_t in the C source where appropriate.

Line 
1<?xml version='1.0' encoding='iso-8859-1'?>
2<section><title>Migrating to version 2.15</title>
3
4<section><title>Changes to plain text conversion</title>
5
6<par>The node method <method>asText</method> has been moved to the
7<module>html</module> namespace, os you have to replace:</par>
8
9<prog>print node.asText()</prog>
10
11<par>with:</par>
12
13<prog>
14from ll.xist.ns import html
15print html.astext(node)
16</prog>
17
18</section>
19
20<section><title>Changes to <class>htmlspecials.pixel</class></title>
21
22<par>If you've been using the <lit>color</lit> attribute for
23<class>htmlspecials.pixel</class>, you have to add a <lit>#</lit> in from of
24the value, as it is a &css; color value now. (And if've you've been using
25<lit>color</lit> and a &css; padding of a different color: This will no longer
26work).</par>
27
28</section>
29
30
31<section><title>Migrating to version 2.14</title>
32
33<section><title>Changes to presenters</title>
34
35<par>Presenters work differently now. Instead of:</par>
36
37<prog>print node.asrepr(presenters.CodePresenter)</prog>
38
39<par>simply do the following:</par>
40
41<prog>print presenters.CodePresenter(node)</prog>
42
43</section>
44
45</section>
46
47
48<section><title>Migrating to version 2.13</title>
49
50<section><title>Changes to <module>ll.xist.xsc</module></title>
51
52<par><method>xsc.Namespace.tokenize</method> no longer has an <arg>encoding</arg>
53argument, but operates on a unicode string directly. You can either use the
54result of a <method>asString</method> call or decode the result of an
55<method>asBytes</method> call yourself.</par>
56</section>
57
58</section>
59
60
61<section><title>Migrating to version 2.11</title>
62
63<section><title>Changes to <module>ll.xist.xsc</module></title>
64
65<par>The function <function>ToNode</function> has been renamed to
66<function>tonode</function>.</par>
67
68<par><class>ll.xist.Context</class> no longer subclasses <class>list</class>.
69If you need a stack for your context, simply add the list as an attribute
70of the context object.</par>
71
72</section>
73
74<section><title>Code rearrangements</title>
75
76<par>The iterator stuff from <module>ll.xist.xfind</module> has been moved to
77the <module>ll</module> package/module, i.e. you have to use
78<function>ll.first</function> instead of <function>ll.xist.xfind.first</function>.</par>
79
80</section>
81
82<section><title>Changes to the <method>walk</method> method</title>
83
84<par>The <method>walk</method> method has changed again. There are no inmodes
85and outmodes any longer. Instead input and output are <class>Cursor</class>
86objects. If you're using your own <method>walk</method> filters, you have to
87update them. For different output modes you can use the methods <method>walknode</method>,
88<method>walkpath</method> or <method>walkindex</method> instead of using
89the cursor yielded by <method>walk</method>.</par>
90
91<par>The node methods <method>find</method> and <method>findfirst</method>
92have been removed. Use <lit>xsc.Frag(node.walk(<rep>...</rep>)</lit> or
93<lit>node.walk(<rep>...</rep>)[0]</lit> instead.</par>
94
95</section>
96
97<section><title>Changes to publishing</title>
98
99<par>Publishing has changed: If you've used the method <method>repr</method>
100before to get a string representation of an &xml; tree, you have to use
101<method>asrepr</method> instead now (<method>repr</method> is a generator
102which will produce the string in pieces).</par>
103
104</section>
105
106
107<section><title>Changes to the <module>xfind</module> module</title>
108
109<par>The functions <function>item</function>, <function>first</function>,
110<function>last</function>, <function>count</function> and
111<function>iterone</function> as well as the class <class>Iterator</class>
112have been moved to the <module>ll</module> module.</par>
113
114</section>
115
116
117<section><title>Migrating to version 2.10</title>
118
119<section><title>Changes to publishing</title>
120<par>Publishing has been changed from using a stream &api; to using a
121iterator &api;. If you've been using <method>Publisher.write</method> or
122<method>Publisher.writetext</method> (in your own <method>publish</method>
123methods) you must update your code by replacing <lit>publisher.write(<rep>foo</rep>)</lit>
124with <lit>yield publisher.encode(<rep>foo</rep>)</lit> and
125<lit>publisher.writetext(<rep>foo</rep>)</lit> with
126<lit>yield publisher.encodetext(<rep>foo</rep>)</lit>.</par>
127</section>
128
129<section><title>Changes to the test suite</title>
130<par>The test suite now uses <link href="http://codespeak.net/py/current/doc/test.html">py.test</link>,
131so if you want to run it you'll need py.test.</par>
132</section>
133
134<section><title>Changes to <module>ll.xist.ns.code</module></title>
135<par>The code in a <class>ll.xist.ns.code.pyexec</class> object is no longer
136executed at construction time, but at conversion time. So if you relied on
137this fact (e.g. to make a namespace available for parsing the rest of the
138&xml; file) you will have to change your code.</par>
139</section>
140
141<section><title>Removed namespaces</title>
142<par>The namespace modules <module>ll.xist.ns.css</module> and
143<module>ll.xist.ns.cssspecials</module> have been removed.</par>
144</section>
145
146</section>
147
148
149<section><title>Migrating to version 2.9</title>
150
151<section><title>Changes to exceptions</title>
152<par>All exception classes have been moved from <module>ll.xist.errors</module>
153to <module>ll.xist.xsc</module>.</par>
154</section>
155
156<section><title>Changes to &xml; name handling</title>
157<par>The class attribute <lit>xmlname</lit> no longer gets replaced with a tuple
158containing both the Python and the &xml; name. If you want to get the Python name,
159use <lit><rep>foo</rep>.__class__.__name__</lit>.</par>
160</section>
161
162<section><title>Changes to the methods <method>walk</method>, <method>find</method> and <method>findfirst</method></title>
163<par>The argument <arg>filtermode</arg> has been renamed to <arg>inmode</arg>
164and (for <method>walk</method>) <arg>walkmode</arg> has been renamed to <arg>outmode</arg>.</par>
165</section>
166
167</section>
168
169
170<section><title>Migrating to version 2.8</title>
171
172<section><title>Changes to display hooks</title>
173<par>The way &xist; uses <function>sys.displayhook</function> has been
174enhanced. To make use of this, you might want to update your Python
175startup script. For more info see the
176<link href="root:xist/Installation.html">installation instructions</link>.</par>
177</section>
178
179<section><title>Changes to the <lit>xmlns</lit> attribute</title>
180<par>Each element (or entity, or processing instruction) class had an attribute
181<lit>xmlns</lit> that references the namespace module. This attribute has been
182renamed to <lit>__ns__</lit>.</par>
183</section>
184
185<section><title>Other minor changes</title>
186<par><class>ll.xist.ns.specials.x</class> has been renamed to
187<class>ll.xist.ns.specials.ignore</class>.</par>
188<par><class>ll.xist.xfind.item</class> no longer handles slices.
189If you've used that functionality, you may now use slices
190on XFind operators, and materilize the result, i.e. replace
191<lit>xfind.slice(<rep>foo</rep>, 1, -1)</lit>
192with <lit>list(<rep>foo</rep>[1:-1])</lit>, if <lit><rep>foo</rep></lit> is
193an XFind operator. Otherwise you can use <lit>list(<rep>foo</rep>)[1:-1]</lit></par>
194</section>
195
196</section>
197
198
199<section><title>Migrating to version 2.7</title>
200
201<section><title>Changes to <module>ll.xist.xfind</module></title>
202<par>The functions <function>xfind.first</function> and
203<function>xfind.last</function> now use <function>xfind.item</function>, so
204they will raise an <class>IndexError</class> when no default value is passed.
205To get the old behaviour, simply pass <lit>None</lit> as the default.</par>
206</section>
207
208</section>
209
210
211<section><title>Migrating to version 2.6</title>
212
213<section><title>Changes to the publishing &api;</title>
214<par>The top level publishing method in the publisher has been
215renamed from <method>dopublication</method> to <method>publish</method>.
216If you're using the publishing &api; directly (instead of the node methods
217<method>asBytes</method> and <method>write</method>), you'll have to
218update your code.</par>
219<par>The method that writes a unicode object to the output stream has
220been renamed from <method>publish</method> to <method>write</method>.
221This is only relevant when you've overwritten the <method>publish</method>
222method in your own node class (e.g. in &jsp; tag library directives
223or similar stuff, or for special nodes that publish some text literally).</par>
224</section>
225
226<section><title>Changes to the presentation &api;</title>
227<par>The presentation &api; has been changed too: The top level presentation
228method in the presenter has been renamed from <method>dopresentation</method> to
229<method>present</method>. This is only relevant if you've written your own
230presenter, or are using the presentation &api; directly (instead of the node
231method <method>repr</method>).</par>
232</section>
233
234<section><title>Parsing &html;</title>
235<par>Parsing &html; is now done via libxml2's &html; parser, instead of using
236µTidyLib of mxTidy. You can no longer pass arguments to tidy. Only the boolean
237values of the <arg>tidy</arg> argument will be used. There are no other visible
238changes to the &api; but the result of parsing might have changed.</par>
239</section>
240
241<section><title>Removed &api;s and scripts</title>
242<par>The script <filename>xscmake.py</filename> has been removed.</par>
243
244<par>The <method>visit</method> method has been removed.</par>
245
246<par><method>ll.xist.xsc.FindOld</method> has been removed.</par>
247
248<par><class>ll.xist.ns.xml.header</class> has been renamed to
249<class>ll.xist.ns.xml.declaration</class>.</par>
250
251</section>
252
253</section>
254
255
256<section><title>Migrating to version 2.5</title>
257
258<section><title>Changes to content model</title>
259<par>The boolean class attribute <lit>empty</lit> for element classes has been
260replaced by an object <lit>model</lit>. <lit>empty</lit> is still supported,
261but issues a <class>PendingDeprecationWarning</class>. If you don't want to specify
262a proper content model for your own elements you can replace <lit>empty = False</lit>
263with <lit>model = True</lit> (which is a shortcut for <lit>model = sims.Any()</lit>)
264and <lit>empty = True</lit> with <lit>model = False</lit> (which is a shortcut
265for <lit>model = sims.Empty()</lit>).</par>
266</section>
267
268</section>
269
270
271<section><title>Migrating to version 2.4</title>
272
273<section><title>Changes to parsing</title>
274<par>Parsing has changed internally, but the module level parsing functions in
275<module>ll.xist.parsers</module> are still available (and will create a parser
276on the fly), but a few arguments have changed:</par>
277<dlist>
278<term><arg>handler</arg></term><item>This argument is no longer available, if you
279need a special handler, you have to subclass <class>ll.xist.parsers.Parser</class>
280and call its parsing methods.</item>
281<term><arg>parser</arg></term><item>This argument has been renamed to
282<arg>saxparser</arg> and is <em>not</em> a &sax;2 parser instance any longer,
283but a callable that will create a &sax;2 parser.</item>
284<term><arg>sysid</arg></term><item><arg>sysid</arg> is now available for all
285parsing functions not just <function>parseString</function>.</item>
286</dlist>
287</section>
288
289<section><title>Changes to converter contexts</title>
290<par><method>ll.xist.converters.Converter.__getitem__</method> now doesn't use
291the key passed in, but <lit><rep>key</rep>.Context</lit> as the real dictionary
292key. This has the following consequences:</par>
293<ulist>
294<item><par>If you want a unique context for your own element class,
295you <em>must</em> implement a new <class>Context</class> class (otherwise you'd
296get <class>ll.xist.xsc.Element.Context</class>):</par>
297<example>
298<prog>
299class Foo(xsc.Element):
300    empty = False
301
302    class Context(xsc.Element.Context):
303        def __init_(self):
304            xsc.Element.Context.__init__(self)
305            <rep>...</rep>
306</prog>
307</example>
308</item>
309<item>Subclasses that don't overwrite <class>Context</class> (as well as instances
310of those classes) can be passed to <method>ll.xist.converters.Converter.__getitem__</method>
311and the unique base class context object will be returned.</item>
312</ulist>
313</section>
314
315<section><title>Changed namespaces</title>
316<par>The character reference classes from <module>ll.xist.ns.ihtml</module>
317that are duplicates of those in <module>ll.xist.ns.chars</module> have been removed, so you
318have to use <module>ll.xist.ns.chars</module> for those characters in addition to
319<module>ll.xist.ns.ihtml</module>
320</par>
321</section>
322
323</section>
324
325
326<section><title>Migrating to version 2.3</title>
327
328<section><title>Changes in namespace handling</title>
329<par>Namespace handling has changed. There are no entity or processing instruction
330prefixes any longer and creating a proper <class>Prefixes</class> object has
331been simplified. For example:</par>
332<prog>
333prefixes = xsc.Prefixes()
334prefixes.addElementPrefixMapping(None, html)
335prefixes.addElementPrefixMapping("svg", svg)
336</prog>
337<par>can be simplified to:</par>
338<prog>
339prefixes = xsc.Prefixes(html, svg=svg)
340</prog>
341<par>The three arguments <arg>elementmode</arg>, <arg>entitymode</arg> and
342<arg>procinstmode</arg> for the publishing methods have been combined into
343<arg>prefixmode</arg>, which is used for elements only.</par>
344</section>
345
346<section><title>Changed namespaces</title>
347<par>The character reference classes from <module>ll.xist.ns.html</module>
348have been moved to a separate namespace <module>ll.xist.ns.chars</module>.</par>
349<par>The processing instructions <class>eval_</class> and <class>exec_</class>
350from the <module>ll.xist.ns.code</module> module have been renamed to
351<class>pyeval</class> and <class>pyexec</class>.</par>
352</section>
353
354<section><title>Changed method names</title>
355<par>The method names <method>beginPublication</method>, <method>endPublication</method>
356and <method>doPublication</method> have been lowercased.</par>
357</section>
358</section>
359
360
361<section><title>Migrating to version 2.2</title>
362
363<section><title>Attribute methods</title>
364
365<par>The <class>Element</class> methods for accessing attributes
366have been deprecated. So instead of <lit><rep>node</rep>.hasattr("<rep>attr</rep>")</lit>,
367you should use:</par>
368
369<prog>
370"<rep>attr</rep>" in <rep>node</rep>.attrs
371</prog>
372
373<par>The same holds for checking whether an attribute is allowed. You can use the following code:</par>
374
375<prog>
376"<rep>attr</rep>" in <rep>node</rep>.Attrs
377</prog>
378
379<par>or:</par>
380
381<prog>
382"<rep>attr</rep>" in <rep>NodeClass</rep>.Attrs
383</prog>
384
385<par>or:</par>
386
387<prog>
388<rep>NodeClass</rep>.isallowed("<rep>attr</rep>")
389</prog>
390
391<par>Many <class>Attrs</class> methods have gained an additional parameter
392<arg>xml</arg>, which specifies whether an attribute name should be
393treated as the &xml; or the Python name of the attribute. Make sure
394that you're not mixing up your arguments in the function call. The
395safest method for this is using keyword arguments, e.g.:</par>
396
397<prog>
398<rep>node</rep>.attr.get("<rep>attr</rep>", default=42)
399</prog>
400
401</section>
402
403<section><title>JSP directive page element</title>
404
405<par>A <lit>contentType</lit> attribute is no longer generated for the
406<class>ll.xist.ns.jsp.directive_page</class>. You have to explicitely use an attribute
407<lit>contentType="<rep>text/html</rep>"</lit> to get a <lit>contentType</lit> attribute
408in the resulting &jsp;. The <lit>charset</lit> option is generated automatically
409from the encoding specified in the publisher.</par>
410
411</section>
412
413<section><title><class>autoimg</class> changes</title>
414
415<par><class>ll.xist.htmlspecials.autoimg</class> will no longer touches existing <lit>width</lit>
416or <lit>height</lit> attributes, so e.g. setting the width to twice the image size via
417<lit>width="2*%(width)s"</lit> no longer works. You have to implement your own
418version of <class>autoimg</class> if you need this.</par>
419
420</section>
421
422<section><title><method>find</method> changes</title>
423
424<par><method>find</method> has been completely rewritten to use the new tree traversal filters.
425For backwards compatibility a filter functor <class>ll.xist.xsc.FindOld</class> exists that
426takes the same arguments as the old <method>find</method> method. I.e. you can replace:</par>
427<prog>
428node.find(
429    type=html.a,
430    attr={"href": None},
431    searchchildren=True
432)
433</prog>
434<par>with:</par>
435<prog>
436node.find(
437    xsc.FindOld(
438        type=html.a,
439        attr={"href": None},
440        searchchildren=True
441    ),
442    skiproot=True
443)
444</prog>
445<par>But one minor difference remains: when <arg>skiproot</arg> is set to true in the new
446<method>find</method> method, the attributes of the root element will <em>not</em> be traversed.
447With the old method they would be traversed.</par>
448
449</section>
450
451<section><title><class>doc</class> changes</title>
452
453<par><class>programlisting</class> has been renamed to <class>prog</class>.</par>
454
455</section>
456
457<section><title>Namespace changes</title>
458
459<par>Namespaces can no longer be instantiated. Instead you have to derive a class
460from <class>Namespace</class>. The <arg>xmlprefix</arg> argument from the constructor
461becomes a class attribute <lit>xmlname</lit> and the argument <arg>xmlname</arg>
462becomes <lit>xmlurl</lit>.</par>
463
464<par>Adding element classes to the namespace is now done with the
465<class>Namespace</class> classmethod <method>update</method>.
466If you want the turn a namespace into a module, you can use the classmethod
467<method>makemod</method> instead of <method>update</method>.</par>
468
469<example><title>Old method</title>
470<prog>
471xmlns = xsc.Namespace("foo", "http://www.foo.com/", vars()
472</prog>
473</example>
474
475<example><title>New method</title>
476<prog>
477class xmlns(xsc.Namespace):
478    xmlname = "foo"
479    xmlurl = "http://www.foo.com/"
480xmlns.makemod(vars())
481</prog>
482</example>
483
484</section>
485
486</section>
487
488
489<section><title>Migrating to version 2.1</title>
490
491<ulist>
492<item>The method <method>withSep</method> has been renamed
493to <method>withsep</method>.</item>
494
495<item>The argument <arg>defaultEncoding</arg> for the various
496parsing functions has been renamed to <arg>encoding</arg>.</item>
497</ulist>
498
499</section>
500
501
502<section><title>Migrating to version 2.0</title>
503
504<section><title>Attribute handling</title>
505
506<par>The biggest change is in the way attributes are defined. In older
507versions you had to define a class attribute <lit>attrHandlers</lit>
508that mapped attribute names to attribute classes. This created problems
509with <z>illegal</z> attribute names (e.g. <lit>class</lit> and <lit>http-equiv</lit>
510in &html;), so for them an ugly workaround was implemented. With 2.0
511this is no longer neccessary. Defining attributes is done via a
512class <class>Attrs</class> nested inside the element class like this:</par>
513
514<example>
515<prog>
516class foo(xsc.Element):
517    class Attrs(xsc.Element.Attrs):
518        class bar(xsc.TextAttr)
519            "The bar attribute"
520            default = "spam"
521            values = ("spam", "eggs")
522            required = True
523        class baz(xsc.URLAttr):
524            "The baz attribute"
525</prog>
526</example>
527
528<par>Default values, set of allowed attributes values and
529whether the attribute is required can be defined via
530class attributes as shown above. You should (directly
531or indirecty) inherit from <class>xsc.Element.Attrs</class>,
532because this class implements handling of global attributes.
533If you want to inherit some attributes (e.g. from your
534base class), you can derive from the appropriate
535<class>Attrs</class> class. Removing an attribute you inherited
536can be done like this:</par>
537
538<example>
539<prog>
540class bar(foo):
541    class Attrs(foo.Attrs):
542        baz = None
543</prog>
544</example>
545
546<par>This removes the attribute <lit>baz</lit> inherited
547from <class>foo</class>.</par>
548
549<par>For attribute names that are no legal Python identifiers,
550the same method can be used as for element classes: Define
551the real &xml; name via a class attribute. This class attribute
552has been renamed from <lit>name</lit> to <lit>xmlname</lit>.</par>
553
554<par>This also means that you always have to use the Python
555name when using attributes now. The &xml; name will only
556be used for parsing and publishing.</par>
557
558<par>&xist; 2.0 tries to be as backwards compatible as
559possible: An existing <lit>attrHandlers</lit> attribute
560will be converted to an <class>Attrs</class> class on the
561fly (and will generate a <class>DeprecationWarning</class> when
562the class is created). An <class>Attrs</class> class will
563automatically generate an <lit>attrHandlers</lit> attribute,
564so it's possible to derive from new element classes in the old way.
565The only situation where this won't work, is with
566attributes where the Python and &xml; name differ, you
567have to use <z>new style</z> attributes there.</par>
568</section>
569
570<section><title>Namespace support</title>
571
572<par>&xist; supports &xml; namespaces now and for parsing it's
573possible to configure which namespaces should be available
574for instantiating classes from. For more info about this
575refer to the documentation for the class <pyref module="ll.xist.xsc" class="Prefixes"><class>Prefixes</class></pyref>.</par>
576
577<par>Before 2.0 the &xml; name for a namespace object
578was pretty useless, now it can be used as the namespace
579name in <lit>xmlns</lit> attributes and it will be used
580for that when publishing and specifying an <lit>elementmode</lit>
581of <lit>2</lit> in the call to the publishing method or the constructor
582of the publisher.</par>
583
584<par>Namespace objects should now be named <lit>xmlns</lit>
585instead of <lit>namespace</lit> as before.</par>
586
587</section>
588
589<section><title>Global attributes</title>
590
591<par>Global attributes are supported now, e.g. the attributes
592<lit>xml:lang</lit> and <lit>xml:space</lit> can be specified
593in an element constructor like this:</par>
594
595<example>
596<prog>
597from ll.xist import xsc
598from ll.xist.ns import html, xml
599
600node = html.html(
601    <rep>content</rep>,
602    {(xml, "lang"): "en", (xml, "space"): "preserve"},
603    lang="en"
604)
605</prog>
606</example>
607
608<par>Instead of the module object (which must contain a
609namespace object named <lit>xmlns</lit>), you can also
610pass the namespace object itself (i.e. <lit>xml.xmlns</lit>)
611or the namespace name (i.e. <lit>"http://www.w3.org/XML/1998/namespace"</lit>).</par>
612
613</section>
614
615<section><title>Namespace changes</title>
616
617<par>The classes <class>XML</class> and <class>XML10</class>
618have been moved from <module>ll.xist.xsc</module> to
619<module>ll.xist.ns.xml</module>.</par>
620
621<par>All the classes in <module>ll.xist.ns.specials</module>
622that are specific to &html; generation have been moved
623to the new module <module>ll.xist.ns.htmlspecials</module>.</par>
624
625<par>The module <module>ll.xist.ns.html</module> has been updated
626to the &xhtml; specification, so there might be some changes.
627The new feature for specifying attribute restrictions has
628been used, so e.g. you'll get warnings for missing <lit>alt</lit>
629attributes in <class>img</class> elements. These warnings
630are issued via the warning framework. Refer to the documentation
631for the <module>warnings</module> module to find out how to
632configure the handling of these warnings.</par>
633
634</section>
635
636<section><title>Miscellaneous</title>
637
638<par>&xist; now requires at least Python 2.2.1 because
639the integer constants <lit>True</lit> and <lit>False</lit>
640are used throughout the code wherever appropriate. These
641constants will become instances of the new class <class>bool</class>
642in Python 2.3. You might want to change your code too, to
643use these new constant (e.g. when setting the element
644class attribute <lit>empty</lit>).</par>
645
646<par>Using mixed case method names was a bad idea, because
647this conflicts with Python's convention of using
648all lowercase names (without underscores). These method
649names will be fixed in the next few &xist; versions.
650The first names that where changed were the element methods
651<method>getAttr</method> and <method>hasAttr</method>, which
652have been renamed to <method>getattr</method> and
653<method>hasattr</method> respectively. <method>getAttr</method>
654and <method>hasAttr</method> are still there and can be called
655without generating <class>DeprecationWarning</class>s, but they
656will start to generate warnings in the upcoming versions.</par>
657
658</section>
Note: See TracBrowser for help on using the browser.