def startElement(self, elname, elattr): "Handle an event for the beginning of an element." attr = {} for name, value in elattr.items(): attr[POM.normalize_unicode(name)] = POM.unescape(value) obj = SimpleXMLNode(elname, attr) self.stack.append(obj)
def get_parser(document=None, namespaces=1, validate=0, external_ges=1, logfile=None, doc_factory=new_document): import xml if hasattr(xml, "use_pyxml"): xml.use_pyxml() import xml.sax.sax2exts import xml.sax.handler handler = POM.ContentHandler(document, doc_factory=doc_factory, logfile=logfile) errorhandler = POM.ErrorHandler(logfile) # create parser parser = xml.sax.sax2exts.XMLParserFactory.make_parser() parser.setFeature(xml.sax.handler.feature_namespaces, namespaces) parser.setFeature(xml.sax.handler.feature_validation, validate) parser.setFeature(xml.sax.handler.feature_external_ges, external_ges) parser.setFeature(xml.sax.handler.feature_external_pes, 0) parser.setFeature(xml.sax.handler.feature_string_interning, 1) # set handlers parser.setContentHandler(handler) parser.setDTDHandler(handler) parser.setEntityResolver(handler) parser.setErrorHandler(errorhandler) return parser
def startElement(self, name, atts): "Handle an event for the beginning of an element." try: klass = self._get_class(name) except AttributeError: raise POM.ValidationError("Undefined element tag: " + name) attr = {} for name, value in atts.items(): attr[keyword_identifier(POM.normalize_unicode(name))] = POM.unescape(value) obj = klass(**attr) self.stack.append(obj)
def verify(self, value): if self._is_enumeration: if value not in self.a_type: raise POM.ValidationError( "Enumeration has wrong value for %r. %r is not one of %r." % (self.name, value, self.a_type)) elif self.a_decl == FIXED: if value != self.default: raise POM.ValidationError( "Bad value for FIXED attrib for %r. %r must be %r." % (self.name, value, self.default)) return True
def startElement(self, name, atts): "Handle an event for the beginning of an element." try: klass = self._get_class(name) except AttributeError: raise POM.ValidationError("Undefined element tag: " + name) attr = {} for name, value in atts.items(): attr[keyword_identifier( POM.normalize_unicode(name))] = POM.unescape(value) obj = klass(**attr) self.stack.append(obj)
def create_POM(data, dtd): """Given a python object, produce reasonable markup from that. Return a valid POM node. Dictionaries produce sections (divs) where key names are the class attribute name; lists produce ordered lists; Sets produce unordered lists; Tuples produce a fragment collection (invisible), an ElementNode is taken as-is, and strings return as Text nodes. Callables are called with the DTD, and the return value checked. """ if data is None: return NBSP # Good representation of nothing? it = type(data) if it is dict: creator = FlowCreator(dtd) outer = POM.Fragments() for name, content in data.iteritems(): div = creator.get_section(name) div.append(create_POM(content, dtd)) outer.append(div) return outer elif it is list: creator = FlowCreator(dtd) ol = creator.get_ordered_list() for item in data: ol.add_item(item) return ol elif it is set: creator = FlowCreator(dtd) ul = creator.get_unordered_list() for item in data: ul.add_item(item) return ul elif it is tuple: frags = POM.Fragments() for item in data: frags.append(create_POM(item, dtd)) return frags elif it is unicode: return POM.Text(data) elif isinstance(data, POM.ElementNode): return data elif it is FunctionType: return check_object(data(dtd)) else: return POM.Text(data)
def check_object(obj): if obj is None: return NBSP if type(obj) in (str, unicode, int, float, long): return POM.Text(str(obj)) if isinstance(obj, POM.ElementNode): return obj raise ValidationError("bad initializer object: should be string or ElementNode instance.")
def endDocument(self): if self.stack: # stack should be empty now raise POM.ValidationError("unbalanced document!") if self.doc is None: self.doc = self._doc_factory(encoding=self.encoding) root = self.msg self.msg = None # Parser strips out namespaces, have to add them back in. if self._prefixes: for uri, prefix in self._prefixes.items(): root.set_attribute(u"xmlns:%s" % prefix, uri) self.doc.set_root(root)
def resolveEntity(self, publicId, systemId): for modname, doctype in dtds.DOCTYPES.items(): if doctype.public == publicId: if self.doc is None: self.doc = self._doc_factory(doctype=modname, encoding=self.encoding) else: self.doc.set_doctype(modname) break else: raise POM.ValidationError("unknown DOCTYPE: %r" % (publicId, )) # Have to fake a file-like object for the XML parser to not # actually get an external entity. return FakeFile(systemId)
def __init__(self, name, a_type, a_decl, a_def=None): self.name = name self._is_enumeration = False a_type_type = type(a_type) if a_type_type is int: # from the generated file self.a_type = POM._ATTRCLASSMAP.get(a_type, a_type) elif a_type_type is unicode: # from the parser self.a_type = _ATTRTYPEMAP.get(a_type, a_type) elif issubclass(a_type_type, list): self.a_type = POM.Enumeration(a_type) self._is_enumeration = True else: self.a_type = a_type # declaration # convert string to int value when generating, just use the int # when imported from Python dtd format. self.a_decl = _DEFAULTMAP.get(a_decl, a_decl) self.default = a_def
def _add_options(self, sl, enums): et = type(enums) if et is Enums and enums: for i, name in enums.choices: opt = self.dtd.Option(value=i) opt.append(POM.Text(name)) sl.append(opt) return if et is dict and enums: for key, val in enums.items(): opt = self.dtd.Optgroup(label=key) self._add_options(opt, val) sl.append(opt) return if et is tuple and enums: name, value = enums opt = self.dtd.Option(value=value) opt.append(POM.Text(name)) return if et is list and enums: for item in enums: it = type(item) if it is tuple: # add "selected" item by adding (value, flag) opt = self.dtd.Option(value=item[0]) opt.append(POM.Text(item[1])) if len(item) > 2 and item[2]: opt.selected = "selected" elif it is dict: # make option groups by passing dictionaries for key, val in item.items(): optgrp = self.dtd.Optgroup(label=key) sl.append(optgrp) self._add_options(optgrp, val) elif it is Enum: # a named number opt = self.dtd.Option(value=int(item)) opt.append(POM.Text(item)) elif it is list: # nested lists will be flattened self._add_options(sl, item) else: opt = self.dtd.Option(value=item) opt.append(POM.Text(item)) sl.append(opt) return else: opt = self.dtd.Option(value=enums) opt.append(POM.Text(enums)) sl.append(opt) return
def get_identifier(self): h = self.__hash__() h = h**2 if h < 0 else h # make non-negative return "attrib%s_%s" % (identifier(POM.normalize_unicode( self.name)), h)
self.set_dtd(DTD) def initialize(self): dtd = self.dtd root = XHTML.get_container(dtd, "Html", {"class_": FEATURE_CLASS}) self.set_root(root) head = XHTML.get_container(dtd, "Head", {}) body = XHTML.get_container(dtd, "Body", {}) head.append(dtd.Meta(charset="utf-8")) head.append( dtd.Meta(http_equiv="X-UA-Compatible", content="IE=edge,chrome=1")) root.append(head) root.append(body) root.head = head root.body = body def new_document(encoding=DEFAULT_ENCODING, language=DEFAULT_LANG): doc = HTML5Document(doctype=DOCTYPE, encoding=encoding, lang=language) doc.initialize() doc.root.lang = language return doc if __name__ == "__main__": import sys from pycopia import autodebug doc = new_document() writer = POM.BeautifulWriter(sys.stdout, XHTML.INLINE) doc.emit(writer)
def test_docencoding(self): import pomtest doc = POM.POMDocument(dtd=pomtest) doc.set_encoding("iso-8859-1") self.assertEqual(doc.encoding, "iso-8859-1")
def test_5POMvalidation(self): import pomtest # previous test just created this. doc = POM.POMDocument(dtd=pomtest) doc.set_root(pomtest.Toplevel()) self.assertRaises(POM.ValidationError, str, doc)
def characters(self, text): if self.stack and text: self.stack[-1].append(POM.Text(text))
def new_preformat(self, text, **kwargs): p = self.get_preformat(**kwargs) t = POM.Text(text) p.append(t) self.append(p) return p
However, it currently lags far behind the XHTML document API. """ import sys from pycopia.XML import POM from pycopia.aid import partial Text = POM.Text # Hand-coded DTD elements for plain text. Note that add_text() is the only # method that makes sense, but is not enforced. # indicates any content ANYCONTENT = POM.ContentModel((True, )) # can contain other nodes attribClass = POM.XMLAttribute('class', 8, 12, None) attribHref = POM.XMLAttribute('href', 1, 12, None) attribLevel = POM.XMLAttribute('level', 1, 12, None) def check_object(obj): if type(obj) in (str, unicode): return POM.Text(obj) if isinstance(obj, POM.ElementNode): return obj raise POM.ValidationError, "bad initializer object" class InlineMixin(object):
def handle_comment(self, data): cmt = POM.Comment(data) try: self.stack[-1].append(cmt) except IndexError: # comment is outside of root node self.comments.append(cmt)
def emit(self, fo): pp = POM.BeautifulWriter(fo) super(XFCE4Menu, self).emit(pp)
def get_identifier(self): h = self.__hash__() h = h**2 if h < 0 else h # make non-negative return "attrib%s_%s" % (identifier(POM.normalize_unicode(self.name)), h)
def show(self, argv): """show Show current document object.""" bw = POM.BeautifulWriter(self._ui) self._obj.emit(bw)
def add_title(self, title): ti = self.head.add(self.dtd.Title) ti.append(POM.Text(title))
def test_1CommentEncoding(self): cmt = POM.Comment("some ------- comment-") self.assert_(str(cmt) == '<!-- some - - - - comment- -->')
def verify(self, value): raise POM.ValidationError("Can't validate unknown attribute: %r" % (self.name, ))
def test_6POMemit(self): import pomtest doc = POM.POMDocument(dtd=pomtest) doc.set_root(pomtest.Toplevel()) doc.root.idval = "someid" # satisfy #REQUIRED attribute doc.emit(sys.stdout)
def get_header(self, level, text, **kwargs): hobj = get_inlinecontainer(self.dtd, "H%d" % (level, ), kwargs) hobj.append(POM.Text(text)) return hobj
def test_negdocencoding(self): import pomtest doc = POM.POMDocument(dtd=pomtest) self.assertRaises(ValueError, doc.set_encoding, "xxx")
def get_header(self, level, text, **kwargs): hobj = Heading(level=level) hobj.append(POM.Text(text)) return hobj
def test_2POMString(self): print repr(POM.POMString(u'This is a test.')) print repr(POM.POMString(u'This is a test.', 'utf-8')) print repr(POM.POMString('This is a test.', 'utf-8'))
def test_XHTML(self): """Construct an XHTML page. Verify visually.""" htd = XHTML.new_document(dtds.XHTML) htd.title = "This is the title." htd.add_header(1, 'Main document & "stuff"') htd.new_para("This is a test. This is text.") htd.add_unordered_list(["List line one.", "list line two."]) BR = htd.get_new_element("Br") A = htd.get_new_element("A", href="somelink.html") A.add_text("some link") p = htd.get_para() p.append(A) p.add_text(" This is ") b = p.bold("bold") p.add_text(" text. using ") stb = htd.get_new_element("B") stb.add_text("bold tags") p.text(stb) p.add_text(" Dynamic Date: ") p.append(XHTML.DynamicNode(thedate)) rp = str(p) htd.append(POM.ASIS(rp)) # table methods t = htd.add_table(border=1) t.summary = "This is a test table." t.caption("table caption") h = t.set_heading(2, "heading col 2") h.set_attribute("class", "headerclass") t.set_heading(1, "heading col 1") t.set_cell(1, 1, "row 1, col 1") t.set_cell(1, 2, "row 2, col 1") t.set_cell(2, 1, "row 1, col 2") t.set_cell(2, 2, "row 2, col 2") # sections div = htd.get_section("section1") div.add_header(1, "Div heading.") div.new_para("First div para.") htd.append(div) div2 = div.get_section("section2") div2.new_para("Second div para") div.append(div2) dl = div.add_definition_list() dl.add_definitions({ "def1": "The definition of 1", "def2": "The definition of 2" }) # using the nodemaker object NM = htd.nodemaker ul = NM( "Ul", None, NM("Li", None, "line 1"), NM("Li", None, "line 2"), NM("Li", None, "Date: ", NM("code", None, thedate)), # another way to add dynamic node ) htd.append(ul) htd.append(NM("JS", None, 'var a = new Array(8);')) # using the creator object. creator = htd.creator parts = creator([("Just", "just/"), "How will this turn out?", ["It is hard to tell.", "Well, not too hard."]]) htd.add_comment( "the name attribute is required for all but submit & reset") htd.append(parts) f = htd.add_form(action="http://localhost:4001/cgi-bin/testing.py", method="post") f.add_textarea("mytextarea", """Default text in the textarea.""") f.append(BR) f.add_input(type="text", name="mytext", value="mytext text") f.append(BR) f.add_input(type="button", name="button1", src="button.png", value="Button") f.append(BR) f.add_input(type="submit", name="submit1", src="submit.png", value="Ok") f.append(BR) f.add_radiobuttons("radlist", ["one", "two", "three", "four"], vertical=False) f.append(BR) f.add_checkboxes("checks", ["one", "two", "three", "four"], vertical=True) f.append(BR) f.add_fileinput(name="myfile", default="/etc/hosts") f.append(BR) f.add_textinput(name="mytext", label="Enter text") f.append(BR) f.yes_no("What's it gonna be?") f.add_select([ "one", "two", ("three", True), "four", { "agroup": ["group1", "group2"] } ], name="myselect") f.append(BR) f.add_select( { "Group1": Enums("g1one", "g1two", "g1three") + [("g1four", True)], "Group2": Enums("g2one", "g2two", "g2three"), "Group3": Enums("g3one", "g3two", "g3three"), }, name="useenums") f.append(BR) f.add_select(["mone", "mtwo", ("mthree", True), ("mfour", True)], name="multiselect", multiple=True) f.append(BR) set = f.add_fieldset("afieldset") set.add_textinput(name="settext", label="Enter set text") set.add_textinput(name="settext2", label="Enter set text 2", default="Default text.") set.append(BR) tbl = htd.new_table([1, 2, 3, 4, 5], [NULL, NULL, NULL], ["col1", "col2", "col3"], width="100%", summary="autogenerated") gentable = table.GenericTable(["heading1", "heading2", "heading3"], title="Sample generic table") gentable.append([1, 2, 3]) gentable.append([4, 5, 6]) tbl2 = htd.new_table_from_GenericTable(gentable) # object subdoc = XHTML.new_document(dtds.XHTML) parts = subdoc.creator( ("Add a document object.", ["Some data.", "some more data.."])) subdoc.append(parts) sdfo = open("/tmp/subdoc.html", "w") subdoc.emit(sdfo) sdfo.close() htd.add_object(data="subdoc.html", type=subdoc.MIMETYPE, width="400px", height="600px") htd.emit(sys.stdout) print "-----" fo = open(XHTMLFILENAME, "w") bw = POM.BeautifulWriter(fo, XHTML.INLINE) htd.emit(bw) fo.close() print "----- Form values:" print f.fetch_form_values() print "----- Form elements:" felems = f.fetch_form_elements() for name, elemlist in felems.items(): print repr(name), ": ", repr(elemlist) print # visually verify the page. webbrowser.open("file://%s" % (XHTMLFILENAME, ))
def check_object(obj): if type(obj) in (str, unicode): return POM.Text(obj) if isinstance(obj, POM.ElementNode): return obj raise POM.ValidationError, "bad initializer object"