; ÕGc@sdZdZdZdkZdkZdkZdklZlZye e e fWn(e j odZ dZ dZ nXei dZd Zd Zei d Zd Zd fdYZdZdefdYZdfdYZhdd<dd<dd<dd<dd<dd<d d!<d"d#<d$d%<d&d'<d(d)<d*d+<d,d-<d.d/<d0d1<d2d3<d4d5<d6d7<d8d9>> from PyMeld import Meld >>> xhtml = ''' ... ... ''' >>> page = Meld(xhtml) # Create a Meld object from XHTML. >>> print page.message # Access an element within the document. >>> print page.message.rows # Access an attribute of an element. 2 >>> page.message = "New message." # Change the content of an element. >>> page.message.rows = 4 # Change an attribute value. >>> del page.message.wrap # Delete an attribute. >>> print page # Print the resulting page. So the program logic and the HTML are completely separated - a graphical designer can design the HTML in a visual XHTML editor, without needing to deal with any non-standard syntax or non-standard attribute names. The program code knows nothing about XML or HTML - it just deals with objects and attributes like any other piece of Python code. Populating an HTML form with a record from a database is a one-liner (using the `%` operator - see below). Building an HTML table from a set of records is just as easy, as shown in the example below: *Real-world example:* Here's a data-driven example populating a table from a data source, basing the table on sample data put in by the page designer. Note that in the real world the HTML would normally be a larger page read from an external file, keeping the data and presentation separate, and the data would come from an external source like an RDBMS. The HTML could be full of styles, images, anything you like and it would all work just the same. >>> xhtml = ''' ... ... ...
Example name21
''' >>> doc = Meld(xhtml) >>> templateRow = doc.row.clone() # Take a copy of the template row, then >>> del doc.row # delete it to make way for the real rows. >>> for name, age in [("Richie", 30), ("Dave", 39), ("John", 78)]: ... newRow = templateRow.clone() ... newRow.name = name ... newRow.age = age ... doc.people += newRow >>> print re.sub(r'\s*', '\n', str(doc)) # Prettify the output
Richie30
Dave39
John78
Note that if you were going to subsequently manipulate the table, using PyMeld or JavaScript for instance, you'd need to rename each `row`, `name` and `age` element to have a unique name - you can do that by assigning to the `id` attribute but I've skipped that to make the example simpler. As the example shows, the `+=` operator appends content to an element - appending `` elements to a `` in this case. *Shortcut: the % operator* Using the `object.id = value` syntax for every operation can get tedious, so there are shortcuts you can take using the `%` operator. This works just like the built-in `%` operator for strings. The example above could have been written like this: >>> for name, age in [("Richie", 30), ("Dave", 39), ("John", 78)]: ... doc.people += templateRow % (name, age) The `%` operator, given a single value or a sequence, assigns values to elements with `id`s in the order that they appear, just like the `%` operator for strings. Note that there's no need to call `clone()` when you're using `%`, as it automatically returns a modified clone (again, just like `%` does for strings). You can also use a dictionary: >>> print templateRow % {'name': 'Frances', 'age': 39} The `%` operator is really useful when you have a large number of data items - for example, populating an HTML form with a record from an RDBMS becomes a one-liner. Note that these examples are written for clarity rather than performance, and don't necessarily scale very well - using `+=` to build up a result in a loop is inefficient, and PyMeld's `%` operator is slower than Python's built-in one. See `toFormatString()` in the reference manual for ways to speed up this kind of code. *Element content* When you refer to a named element in a document, you get a Meld object representing that whole element: >>> page = Meld('Hello world') >>> print page.x Hello world If you just want to get the content of the element as string, use the `_content` attribute: >>> print page.x._content Hello world You can also assign to `_content`, though that's directly equivalent to assigning to the tag itself: >>> page.x._content = "Hello again" >>> print page Hello again >>> page.x = "Goodbye" >>> print page Goodbye The only time that you need to assign to `_content` is when you've taken a reference to an element within a document: >>> x = page.x >>> x._content = "I'm back" >>> print page I'm back Saying `x = "I'm back"` would simply re-bind `x` to the string `"I'm back"` without affecting the document. *Version and license* This is version 2.1.3 of PyMeld, Copyright (c) 2005 Entrian Solutions. It is released under the terms of the Sleepycat License (see the top of _PyMeld.py_), which allows Open Source products to freely redistribute it in source or binary form. Commercial licensing is available for a fee; contact _richie@entrian.com_ for more information. Version 1.0 had a different API which is now deceased. If you need advice on upgrading your code to use the new API (which should be trivial), or you need a copy of PyMeld 1.0, please contact _richie@entrian.com_. s2.1.3s"Richie Hindle N(s StringTypes UnicodeTypeiicCs | SdS(N(sx(sx((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pysboolss (?ix) # Case-insensitive, verbose <(?P[-a-z0-9_:.]+) # Tag opens; capture its name (?:\s+[-a-z0-9_:.]+=(?P["']).*?(?P=quote1))* # Attributes \s*/?> # Tag closes s(?ix) # Case-insensitive, verbose <(?P[-a-z0-9_:.]+) # Tag opens; capture its name (?:\s+[-a-z0-9_:.]+=(?P["']).*?(?P=quote1))* # Attributes before id \s+id=(?P["'])(?P%s)(?P=quote2) # The 'id' tag (?:\s+[-a-z0-9_:.]+=(?P["']).*?(?P=quote3))* # Attributes after id \s*/?> # Tag closes sS(?ix) (?P\s+) (?P%s)=(?P["'])(?P.*?)(?P=quote) s.(?i)\s+id=(?P["'])(?P.*?)(?P=quote)cCst|}d}ti||}|}xM|oE|}|i dd}ti|d||||i !}q+W|SdS(sWork around a possible RE bug: > m = re.search(r"<\w+(?:\s\w+='.*?')*\sid='x'>", "") > m.span() (0, 25) iis.N( s openIDTagREsidsthisREsstartsressearchstextsmatchs prevMatchsspansend(sidstextsthisREs prevMatchsstartsmatch((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys _findIDMatch s ,s _MarkupHoldercBs tZdZdZdZRS(s\Keeps hold of the markup string, so that it can be shared between multiple Meld objects.cCsd|_||_dS(Ni(sselfscountss(sselfss((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys__init__$s cCs6||i|<|djo|id|id>> html = '
xxx
' >>> meld = Meld(html, replaceUnderscoreWithDash=True) >>> meld.header_box = "Yay!" >>> print meld.header_box
Yay!
>>> del meld.header_box >>> print meld is&Melds must be constructed from stringsN(sreadonlysselfs _readonlysreplaceUnderscoreWithDashs_dashesssourcesNones isinstances StringTypes UnicodeTypes _MarkupHolders_markups _lastUpdates_names TypeError(sselfssourcesreadonlysreplaceUnderscoreWithDash((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys__init__:s       cCsKtt|i|i}|i|_d|_||_ |i ||SdS(sAlternative constructor for internal use: makes a child Meld for a named element. `start` is a shortcut - everywhere where this is used, we've already found the starting position of the child element as a side effect of determining that the element exists.iN( sMeldsNonesselfs _readonlys_dashess newObjects_markups _lastUpdatesnames_names_updatePositionssstart(sselfsnamesstarts newObject((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys _makeChildVs    cCs|i|iijodSn|itjoatit|ii }| o t dn|i d|_ |i|_|i|_n|tjoLt|i|ii }|i d|_ |i|_|i|_nUtit|ii |}|i d|_ ||i|_||i|_|ii |i}d}d}xnotid|i ||}tid|i ||}| o|i|_|_Pq^| op|djoA|i||id|_|i||id|_Pq|d}||id}q^|id|idjo"|d}||id}q^|d}|djoA|i||id|_|i||id|_Pq^||id}qeW|ii|_dS(sFinds the start and end positions of the start and end tag in the markup. If the caller happens to know where the start tag starts, he can pass it in to save time.Ns)This isn't any form of markup I recognizestagiis (?i)<%s(>|\s)s (?i)(sselfs _lastUpdates_markupscounts_namesNonesressearchs openTagREsssmatchs ValueErrorsgroups_tagNamesstarts _openStartsends_openEnds _findIDMatchsrestsdepthsposs openMatchs closeMatchs _closeStarts _closeEndsspan(sselfsstarts openMatchsrestspossdepths closeMatchsmatch((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys_updatePositionscs\    !   cCs|i|itjo#|i}|ii||i!}n |i }|ii||i !}t ||}|o||iSntSdS(sMReturns the start position of the element with the given ID, or None.N(sselfs_updatePositionss_namesNones _openStartsstarts_markupsss _closeEndssubsets_openEnds _closeStarts _findIDMatchsnodeIDsmatch(sselfsnodeIDssubsetsstartsmatch((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys_findElementFromIDs   cCsM|idd}|iddidd}tidd|}|Sd S( sXMinimally quotes an attribute value, using `"`, `&`, `<` and `>`.s"s"ss>s&(?![a-zA-Z0-9]+;)s&N(svaluesreplacesressub(sselfsvalue((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys_quoteAttributes cCs>|iddidd}|iddiddSd S( s:Unquotes an attribute value quoted by `_quoteAttribute()`.s"s"s&s&s<sN(svaluesreplace(sselfsvalue((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys_unquoteAttributescCs3|djo%|i|ii|i|i!SnD|ddjo2y|i|SWqutj ot |quXn|i ot i |dd}n|i|i |}|tj o|i||Sn|ii|i|i!}tit||}|o|i|idSnt d|dS(s`object.`, if this Meld contains an element with an `id` attribute of `name`, returns a Meld representing that element. Otherwise, `object.` returns the value of the attribute with the given name, as a string. If no such attribute exists, an AttributeError is raised. `object._content` returns the content of the Meld, not including the enclosing ``, as a string. >>> p = Meld('

Hello World

') >>> print p.who World >>> print p.style one >>> print p._content Hello World >>> print p.who._content World s_contentis_s-svalues No element or attribute named %rN(snamesselfs_updatePositionss_markupsss_openEnds _closeStarts__dict__sKeyErrorsAttributeErrors_dashessstringsreplaces_findElementFromIDsstartsNones _makeChilds _openStartsopenTagsressearchs attributeREsmatchs_unquoteAttributesgroup(sselfsnamesstartsopenTagsmatch((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys __getattr__s(     cCs|ddjo |djo||i| = value` sets the XML content of the element with an `id` of `name`, or if no such element exists, sets the value of the `name` attribute on the outermost element. If the attribute is not already there, a new attribute is created. >>> p = Meld('

Hello World

') >>> p.who = "Richie" >>> p.style = "two" >>> p.align = "center" >>> p.who.id = "newwho" >>> print p

Hello Richie

is_s_contentNs-squotes %s%s=%s%s%ssspacesnameis %s="%s"sid(-snamesvaluesselfs__dict__s _readonlys ReadOnlyErrorsREAD_ONLY_MESSAGEs_dashessstringsreplaces_updatePositionss isinstances StringTypes UnicodeTypesstrs_markupsss_openEnds _closeStarts_findElementFromIDsstartsNones _makeChildschilds _openStarts _closeEndsopenTagsressearchs attributeREsattributeMatchs_quoteAttributes escapedValuesspansattributeStarts attributeEndsgroupsquotes newOpenTagslens_tagNamesnewAttributePoss newAttributeslowers_name(sselfsnamesvalues newOpenTags attributeEndsattributeMatchsattributeStarts escapedValuesstartsnewAttributePossopenTagsquotes newAttributeschild((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys __setattr__sB      ! .  2;2(c Cs|djo<|i|ii|i |ii|i|i_dSn|ddjo5y|i|=dSWqtj ot |qXn|i o t t n|i oti|dd}n|i|i|}|tj oD|i||}|ii|i |ii|i|i_dSn|ii|i|i!}tit||}|oV|i\}}|| ||}|ii|i ||ii|i|i_nt d|dS(sDeletes the named element or attribute from the `Meld`: >>> p = Meld('

Hello World

') >>> del p.who >>> del p.style >>> print p

Hello

s_contentNis_s-s No element or attribute named %r( snamesselfs_updatePositionss_markupsss_openEnds _closeStarts__dict__sKeyErrorsAttributeErrors _readonlys ReadOnlyErrorsREAD_ONLY_MESSAGEs_dashessstringsreplaces_findElementFromIDsstartsNones _makeChildschilds _openStarts _closeEndsopenTagsressearchs attributeREsattributeMatchsspansattributeStarts attributeEnds newOpenTag( sselfsnames newOpenTags attributeEndsstartsattributeMatchschildsattributeStartsopenTag((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys __delattr__;s8  *      *2c Cs|i}|it|do t|io|i}|i}nWt|dot |t  p t |t ot }t |}nt }|g}|ox?t||D]\} } |ioti| dd} nt | t  p t | t ot| } n|i| }|t j oD|i| |} |ii| i | |ii| i|i_qqWnk|i|i}x|o|i} t | t  p t | t ot| } n|ii||i!}t!d|}| o t#dn|i|i$d||i} |ii| i | |ii| i|i_t%| | i| i} |i| 7_|i'| 7_'| i'| }qW|ii||i!}t!d|}|o t#dn|Sd S( s`object % value`, `object % sequence`, or `object % dictionary` all mimic the `%` operator for strings: >>> xml = 'Hello World' >>> x = Meld(xml) >>> print x % ("Howdy", "everybody") Howdy everybody >>> print x % {'who': 'all'} Hello all Assignment for sequences happens in the same order that nodes with 'id' attributes appear in the document, not including the top-level node (because if the top-level node were included, you'd only ever be able to assign to that and nothing else): >>> xml = '''
... ... First one ... Second one ... ... Third one; the content includes 'f': ... Removed when 'e' is assigned to ... ... ''' >>> a = Meld(xml) >>> print a % ('One, with a new node', 'Two', 'Three') One, with a new node Two Three Giving the wrong number of elements to `%` raises the same exceptions as the builtin string `%` operator. Unlike the builtin `%` operator, dictionaries don't need to specify all the keys: >>> print x % "Howdy" Traceback (most recent call last): ... TypeError: not enough arguments >>> print x % ("Howdy", "everybody", "everywhere") Traceback (most recent call last): ... TypeError: not all arguments converted >>> print x % {"greeting": "Howdy"} Howdy World svaluess __getitem__s_s-s[^'"]*snot all arguments convertedsidsnot enough argumentsN((sselfsclonesnews_updatePositionsshasattrsvaluesscallableskeysssequences isinstances StringTypes UnicodeTypesNoneslistszipskeysvalues_dashessstringsreplacesstrs_findElementFromIDsstarts _makeChildschilds_markupsss_openEnds _closeStartsreversesposspopssubsets _findIDMatchsmatchs TypeErrorsgroupslens addedSizes _closeEnd( sselfsvaluesssubsetssequencespossstartsnewsmatchskeysskeyschilds addedSizesvalue((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys__mod__hsX1    1   ! :   ! %. cCs|i|ii|i|i!}tid|}h}xE|D]=\}}|i oti|dd}nd|||>> xhtml = '''
Frances39
... ... ...
Example21
''' >>> doc = Meld(xhtml) >>> rowFormat = doc.row.toFormatString() >>> rows = [] >>> for name, age in [("Richie", 30), ("Dave", 39), ("John", 78)]: ... rows.append(rowFormat % (name, age)) >>> doc.people = '\n' + doc.header + ''.join(rows) >>> print re.sub(r'\s*', '\n', str(doc)) # Prettify
Richie30
Dave39
John78
So the inner loop no longer contains any PyMeld calls at all - it only manipulates strings and lists. Here's what `doc.row.toFormatString()` actually returns - note that this is a string, not a PyMeld object: >>> print doc.row.toFormatString() %s%s You can ask for a format string that expects a dictionary rather than a tuple using the `useDict` parameter: >>> print doc.row.toFormatString(useDict=True) %(name)s%(age)s If your markup contains `%` symbols, they are correctly quoted in the resulting format string: >>> doc = Meld("

10% gin.

") >>> print doc.toFormatString()

10%% %s.

>>> print doc.toFormatString() % 'vodka'

10% vodka.

s\bid=(["\'])([^"\']+)\1s-s_s:PyMeldMarker'%s':s%s%%s:PyMeldMarker'([^']+)':s%(\1)ss:PyMeldMarker'[^']+':s%sN(sselfs_updatePositionss_markupsss_openEnds _closeStartscontentsresfindalls quotesAndKeyss keysToMarkerss unusedQuoteskeys_dashessstringsreplacesstrsformatsuseDictssub(sselfsuseDicts unusedQuotes quotesAndKeysskeys keysToMarkerssformatscontent((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pystoFormatStrings/   icCs7|i|ii|i|i!}t|||SdS(sfCreates a clone of a `Meld`, for instance to change an attribute without affecting the original document: >>> p = Meld('

Hello World

') >>> q = p.clone() >>> q.who = "Richie" >>> print q.who Richie >>> print p.who World N( sselfs_updatePositionss_markupsss _openStarts _closeEndsmarkupsMeldsreadonlysreplaceUnderscoreWithDash(sselfsreadonlysreplaceUnderscoreWithDashsmarkup((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pysclones  cCs`t|to'|i|ii|i|i!}n|i|ii|i|i!|SdS(s`object1 + object2` turns both objects into strings and returns the concatenation of the strings: >>> a = Meld('1') >>> b = Meld('2') >>> c = Meld('3') >>> print a + b 12 >>> print a.x + b.y + c.z 123 N( s isinstancesothersMelds_updatePositionss_markupsss _openStarts _closeEndsself(sselfsother((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys__add__/s   cCs)|i||ii|i|i!SdS(s See `__add__`N(sselfs_updatePositionssothers_markupsss _openStarts _closeEnd(sselfsother((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys__radd__Bs cCs|io ttnt|to'|i|ii |i |i !}n|i|ii |i ||ii |i |i_ |SdS(s`object1 += object2` appends a string or a clone of a Meld to the end of another Meld's content. This is used to build things like HTML tables, which are collections of other objects (eg. table rows). See *Real-world example* in the main documentation.N( sselfs _readonlys ReadOnlyErrorsREAD_ONLY_MESSAGEs isinstancesothersMelds_updatePositionss_markupsss _openStarts _closeEnds _closeStart(sselfsother((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys__iadd__Is    .cCsO|i|itjot|iiSnt|ii|i|i!SdS(sReturns the XML that this `Meld` represents. Don't call this directly - instead convert a `Meld` to a string using `str(object)`. `print` does this automatically, which is why none of the examples calls `str`.N( sselfs_updatePositionss_namesNonesstrs_markupsss _openStarts _closeEnd(sself((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys__str__Zs  cCs+|it|ii|i|i!SdS(s9Returns the XML that this `Meld` represents. Don't call this directly - instead convert a `Meld` to unicode using `unicode(object)`. `print` does this automatically, which is why none of the examples calls `str`. Note that PyMeld's ability to handle Unicode is largely untested.N(sselfs_updatePositionssunicodes_markupsss _openStarts _closeEnd(sself((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys __unicode__fs (s__name__s __module__s__doc__sFalses__init__s _makeChildsNones_updatePositionss_findElementFromIDs_quoteAttributes_unquoteAttributes __getattr__s __setattr__s __delattr__s__mod__stoFormatStringsclones__add__s__radd__s__iadd__s__str__s __unicode__(((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pysMeld4s$  K    + A - n H    sentities and charrefss% >>> page = Meld('''• This "and that"... ... x''') >>> print page.s.title "Quoted" & Not >>> page.s.title = page.s.title # Accept liberally, produce strictly. >>> print page • This "and that"... x >>> page.s.title = page.s.title + " <>" >>> print page.s.title "Quoted" & Not <> >>> print page.s x sassigning to _contents >>> page = Meld('''Old''') >>> page.s._content = "New" >>> print page New >>> page._content = "All new" >>> print page All new sdeleting _contents >>> page = Meld('''Old''') >>> del page.s._content >>> print page s!constructing from an unknown typesm >>> page = Meld(1) Traceback (most recent call last): ... TypeError: Melds must be constructed from strings s"accessing a non-existent attributes; >>> page = Meld('') >>> print page.spam Traceback (most recent call last): ... AttributeError: No element or attribute named 'spam' >>> del page.spam Traceback (most recent call last): ... AttributeError: No element or attribute named 'spam' >>> print page.body.spam # For non-container Melds Traceback (most recent call last): ... AttributeError: No element or attribute named 'spam' >>> del page.body.spam # For non-container Melds Traceback (most recent call last): ... AttributeError: No element or attribute named 'spam' sadd new thingss >>> page = Meld('''''') >>> page.empty = "Not any more" >>> page.empty.cols = 60 >>> print page sreadonlys3 >>> page = Meld('''No!''', readonly=True) >>> page.no = "Yes?" Traceback (most recent call last): ... ReadOnlyError: You can't modify this read-only Meld object >>> page.no.attribute = "Yes?" Traceback (most recent call last): ... ReadOnlyError: You can't modify this read-only Meld object >>> page.no += "More?" Traceback (most recent call last): ... ReadOnlyError: You can't modify this read-only Meld object >>> del page.no Traceback (most recent call last): ... ReadOnlyError: You can't modify this read-only Meld object scopy from one to anothersB >>> a = Meld('One') >>> b = Meld('Two') >>> a.one = b.two >>> print a Two >>> b.two = "New" >>> print a # Checking for side-effects Two smixed-type add, radd and iadds >>> a = Meld('1') >>> print a.one + "x" 1x >>> print "x" + a.one x1 >>> a.one += "y" >>> print a 1y saccess top-level elementsE >>> d = Meld("spam") >>> print d.x spam s$access nested element with same names >>> d = Meld("spam") >>> print d.x.x spam >>> d = Meld("spam") >>> print d.x.x spam sunicodesO >>> u = Meld(u'One') >>> a = Meld('Two') >>> u.one = a.two >>> print repr(unicode(u)) u'Two' >>> a.two = Meld(u'') >>> print a sprivate attributessi >>> page = Meld('x') >>> page._private = "Spam" >>> print repr(page._private) 'Spam' >>> print page x >>> del page._private >>> print repr(page._private) Traceback (most recent call last): ... AttributeError: _private >>> del page._private Traceback (most recent call last): ... AttributeError: _private >>> print page x s no markups >>> page = Meld("Hello world") >>> print page.spam Traceback (most recent call last): ... ValueError: This isn't any form of markup I recognize snestings >>> page = Meld(''' ... Hello ... World ... and friends ... ! ... Goodbye ... ... ''') >>> print page.all Hello World and friends ! Goodbye >>> print page.extra and friends sre-bugs >>> page = Meld("") >>> print page.x # Was "" s underscoress >>> html = '
xxx
' >>> meld = Meld(html, replaceUnderscoreWithDash=True) >>> print meld % {'header_box': 'Mod'}
Mod
>>> print meld.toFormatString(useDict=True)
%(header_box)s
>>> meld.header_box = 'yyy' >>> meld.header_box.dash_attr = '___' >>> print meld
yyy
sdoctypes >>> html = '\nz' >>> meld = Meld(html) >>> meld.a = 'a' >>> meld.y = 'b' >>> print meld b s eichin-bugs5 >>> page = Meld(''' ...
label Running
''') >>> print page.Instance_1_4 Running cCsdk}ydkl}|idWntj o t}nXdk}|i|}|o|i }|i n|SdS(sTests the `PyMeld` module, performing code coverage analysis if `Entrian.Coverage` is available. Returns `(failed, total)`, a la `doctest.testmod`.N(sCoveragesPyMeld( sdoctestsEntriansCoveragesstarts ImportErrorsFalsesPyMeldstestmodsresults getAnalysissanalysiss printAnalysis(sPyMeldsanalysissdoctestsCoveragesresult((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pystest]s     s__main__sAll %d tests passed.(s__doc__s __version__s __author__ssyssstringsrestypess StringTypes UnicodeTypesTruesFalsesbools NameErrorscompiles openTagREs openIDTagREs attributeREsidREs _findIDMatchs _MarkupHoldersREAD_ONLY_MESSAGEs Exceptions ReadOnlyErrorsMelds__test__stests__name__sfailedstotal(stotalsMelds StringTypes openTagREsfailedsresbools attributeREs __version__sTrues openIDTagREsstringsREAD_ONLY_MESSAGEs __author__ssysstests__test__s _MarkupHolders _findIDMatchsFalsesidREs UnicodeTypes ReadOnlyError((s4/mnt/gmirror/ports/www/py-meld/work/PyMeld/PyMeld.pys?s6  B !