def sendPresence(pytrans, to, fro, show=None, status=None, priority=None, ptype=None, avatarHash=None, nickname=None, payload=[], url=None): if ptype in ["subscribe", "subscribed", "unsubscribe", "unsubscribed"]: to = internJID(to).userhost() fro = internJID(fro).userhost() el = Element((None, "presence")) el.attributes["to"] = to el.attributes["from"] = fro if ptype: el.attributes["type"] = ptype if show: s = el.addElement("show") s.addContent(utils.xmlify(show)) if status: s = el.addElement("status") s.addContent(utils.xmlify(status)) if priority: s = el.addElement("priority") s.addContent(priority) if url: s = el.addElement("x") s.attributes["xmlns"] = globals.XOOB s = el.addElement("url") s.addContent(url) if not ptype: if avatarHash and not config.disableAvatars and not config.disableVCardAvatars: x = el.addElement("x") x.attributes["xmlns"] = globals.VCARDUPDATE p = x.addElement("photo") p.addContent(avatarHash) if nickname: x = el.addElement("x") x.attributes["xmlns"] = globals.VCARDUPDATE n = x.addElement("nickname") n.addContent(nickname) if avatarHash and not config.disableAvatars and not config.disableIQAvatars: x = el.addElement("x") x.attributes["xmlns"] = globals.XAVATAR h = x.addElement("hash") h.addContent(avatarHash) if nickname and ptype == "subscribe": n = el.addElement("nick") n.attributes["xmlns"] = globals.NICK n.addContent(nickname) if payload: for p in payload: el.addChild(p) pytrans.send(el)
def gotvCard(self, profile, user, vcard, d): from glue import aim2jid LogEvent(INFO, self.session.jabberID) cutprofile = oscar.dehtml(profile) nickname = vcard.addElement("NICKNAME") nickname.addContent(utils.xmlify(user)) jabberid = vcard.addElement("JABBERID") jabberid.addContent(aim2jid(user)) desc = vcard.addElement("DESC") desc.addContent(utils.xmlify(cutprofile)) d.callback(vcard)
def gotAIMvCard(self, profile, user, vcard, d): from glue import icq2jid LogEvent(INFO, self.session.jabberID) cutprofile = oscar.dehtml(profile) nickname = vcard.addElement("NICKNAME") nickname.addContent(utils.xmlify(user)) jabberid = vcard.addElement("JABBERID") jabberid.addContent(icq2jid(user)) desc = vcard.addElement("DESC") desc.addContent(utils.xmlify(cutprofile)) d.callback(vcard)
def setAway(self, awayMessage=None): LogEvent(INFO, self.session.jabberID) try: self.bos.awayResponses = {} self.bos.setAway(utils.xmlify(awayMessage)) except AttributeError: #self.alertUser(lang.get("sessionnotactive", config.jid)) pass
def gotnovCard(self, profile, user, vcard, d): from glue import icq2jid LogEvent(INFO, self.session.jabberID) nickname = vcard.addElement("NICKNAME") nickname.addContent(utils.xmlify(user)) jabberid = vcard.addElement("JABBERID") jabberid.addContent(icq2jid(user)) desc = vcard.addElement("DESC") desc.addContent("User is not online.") d.callback(vcard)
def sendMessage(pytrans, to, fro, body=None, mtype=None, delay=None, xhtml=None, nickname=None, receipt=None, mID=None): """ Sends a Jabber message """ LogEvent(INFO) el = Element((None, "message")) el.attributes["to"] = to el.attributes["from"] = fro if mID: el.attributes["id"] = mID else: el.attributes["id"] = pytrans.makeMessageID() if mtype: el.attributes["type"] = mtype if delay: x = el.addElement("x") x.attributes["xmlns"] = globals.XDELAY x.attributes["from"] = fro x.attributes["stamp"] = delay if nickname: n = el.addElement("nick") n.attributes["xmlns"] = globals.NICK n.addContent(nickname) if receipt: r = el.addElement("received") r.attributes["xmlns"] = globals.RECEIPTS else: # do not send state info in message receipt x = el.addElement("x") x.attributes["xmlns"] = globals.XEVENT composing = x.addElement("composing") xx = el.addElement("active") xx.attributes["xmlns"] = globals.CHATSTATES if body: b = el.addElement("body") b.addContent(utils.xmlify(body)) if xhtml and not config.disableXHTML: try: el.addChild(utils.parseText(xhtml)) except: # Hrm, didn't add, we're not going to end the world # because of it. pass pytrans.send(el) sendArchive(pytrans, to, fro, body)
def sendMessage(pytrans, to, fro, body, mtype=None, delay=None, xhtml=None, nickname=None): """ Sends a Jabber message """ LogEvent(INFO) el = Element((None, "message")) el.attributes["to"] = to el.attributes["from"] = fro el.attributes["id"] = pytrans.makeMessageID() if mtype: el.attributes["type"] = mtype if delay: x = el.addElement("x") x.attributes["xmlns"] = globals.XDELAY x.attributes["from"] = fro x.attributes["stamp"] = delay if nickname: n = el.addElement("nick") n.attributes["xmlns"] = globals.NICK n.addContent(nickname) b = el.addElement("body") b.addContent(utils.xmlify(body)) x = el.addElement("x") x.attributes["xmlns"] = globals.XEVENT composing = x.addElement("composing") xx = el.addElement("active") xx.attributes["xmlns"] = globals.CHATSTATES if xhtml and not config.disableXHTML: try: el.addChild(utils.parseText(xhtml)) except: # Hrm, didn't add, we're not going to end the world # because of it. pass pytrans.send(el) sendArchive(pytrans, to, fro, body)
def sendArchive(pytrans, to, fro, body): """ Archive Jabber message if archive element set in config.xml """ """ send iq xml packet to server specified in archive element """ """ Configured for DataSink """ """ THIS IS NOT COMPLIANT WITH JEP-0136 """ if config.messageArchiveJID: LogEvent(INFO) iq = Element((None, "iq")) iq.attributes["type"] = "set" iq.attributes["from"] = to iq.attributes["to"] = config.messageArchiveJID myarchive = iq.addElement("archive") mymessage = myarchive.addElement("message") mymessage.attributes["to"] = to mymessage.attributes["from"] = fro mybody = mymessage.addElement("body") mybody.addContent(utils.xmlify(body)) pytrans.iq.sendIq(iq)
def gotvCard(self, usercol): from glue import icq2jid LogEvent(INFO, self.session.jabberID) if usercol != None and usercol.valid: vcard = usercol.vcard fn = vcard.addElement("FN") fn.addContent(utils.xmlify(usercol.first + " " + usercol.last)) n = vcard.addElement("N") given = n.addElement("GIVEN") given.addContent(utils.xmlify(usercol.first)) family = n.addElement("FAMILY") family.addContent(utils.xmlify(usercol.last)) middle = n.addElement("MIDDLE") nickname = vcard.addElement("NICKNAME") nickname.addContent(utils.xmlify(usercol.nick)) if usercol.nick: #unick,uenc = oscar.guess_encoding(usercol.nick, config.encoding) #self.legacyList.updateNickname(usercol.userinfo, unick) self.legacyList.updateNickname(usercol.userinfo, usercol.nick) bday = vcard.addElement("BDAY") bday.addContent(utils.xmlify(usercol.birthday)) desc = vcard.addElement("DESC") desc.addContent(utils.xmlify(usercol.about)) try: c = self.legacyList.ssicontacts[usercol.userinfo] desc.addContent(utils.xmlify("\n\n-----\n"+c['lanipaddr']+'/'+c['ipaddr']+':'+"%s"%(c['lanipport'])+' v.'+"%s"%(c['icqprotocol']))) except: pass url = vcard.addElement("URL") url.addContent(utils.xmlify(usercol.homepage)) # Home address adr = vcard.addElement("ADR") adr.addElement("HOME") street = adr.addElement("STREET") street.addContent(utils.xmlify(usercol.homeAddress)) locality = adr.addElement("LOCALITY") locality.addContent(utils.xmlify(usercol.homeCity)) region = adr.addElement("REGION") region.addContent(utils.xmlify(usercol.homeState)) pcode = adr.addElement("PCODE") pcode.addContent(utils.xmlify(usercol.homeZIP)) ctry = adr.addElement("CTRY") ctry.addContent(utils.xmlify(usercol.homeCountry)) # home number tel = vcard.addElement("TEL") tel.addElement("VOICE") tel.addElement("HOME") telNumber = tel.addElement("NUMBER") telNumber.addContent(utils.xmlify(usercol.homePhone)) tel = vcard.addElement("TEL") tel.addElement("FAX") tel.addElement("HOME") telNumber = tel.addElement("NUMBER") telNumber.addContent(utils.xmlify(usercol.homeFax)) tel = vcard.addElement("TEL") tel.addElement("CELL") tel.addElement("HOME") number = tel.addElement("NUMBER") number.addContent(utils.xmlify(usercol.cellPhone)) # email email = vcard.addElement("EMAIL") email.addElement("INTERNET") email.addElement("PREF") emailid = email.addElement("USERID") emailid.addContent(utils.xmlify(usercol.email)) # work adr = vcard.addElement("ADR") adr.addElement("WORK") street = adr.addElement("STREET") street.addContent(utils.xmlify(usercol.workAddress)) locality = adr.addElement("LOCALITY") locality.addContent(utils.xmlify(usercol.workCity)) region = adr.addElement("REGION") region.addContent(utils.xmlify(usercol.workState)) pcode = adr.addElement("PCODE") pcode.addContent(utils.xmlify(usercol.workZIP)) ctry = adr.addElement("CTRY") ctry.addContent(utils.xmlify(usercol.workCountry)) tel = vcard.addElement("TEL") tel.addElement("WORK") tel.addElement("VOICE") number = tel.addElement("NUMBER") number.addContent(utils.xmlify(usercol.workPhone)) tel = vcard.addElement("TEL") tel.addElement("WORK") tel.addElement("FAX") number = tel.addElement("NUMBER") number.addContent(utils.xmlify(usercol.workFax)) jabberid = vcard.addElement("JABBERID") jabberid.addContent(utils.xmlify(usercol.userinfo+"@"+config.jid)) usercol.d.callback(vcard) elif usercol: usercol.d.callback(usercol.vcard) else: self.session.sendErrorMessage(self.session.jabberID, uin+"@"+config.jid, "cancel", "undefined-condition", "", "Unable to retrieve user information")
def traverse_dom_for_cnxml(self, element): # traverse every element in tree, find matching environments, transform for child in element: self.traverse_dom_for_cnxml(child) childIndex = 0 while childIndex < len(element): child = element[childIndex] if child.tag in ["video", "simulation", "presentation", "box"]: child.tag = "todo-" + child.tag childIndex += 1 elif child.tag == "image": # <image> <arguments/> <src/> </image> mediaNode = utils.create_node("media") mediaNode.append(utils.create_node("image")) mediaNode.attrib["alt"] = "Image" urlNode = child.find("src") if urlNode is not None: mediaNode[0].attrib["src"] = urlNode.text.strip() else: mediaNode[0].attrib["src"] = "" mediaNode.tail = child.tail element[childIndex] = mediaNode childIndex += 1 elif child.tag == "figure": typeNode = child.find("type") if typeNode is not None: typ = typeNode.text.strip() child.attrib["type"] = typ typeNode.tag = "label" typeNode.text = {"figure": "Figure", "table": "Table"}[typ] childIndex += 1 elif child.tag == "caption": if (len(child) == 1) and (child[0].tag == "para"): utils.etree_replace_with_node_list(child, child[0], child[0]) childIndex += 1 elif child.tag == "activity": # <activity type="activity"><title/> <section><title/>...</section> </activity> child.tag = "example" child.append( utils.create_node( "label", text={ "g_experiment": "General experiment", "f_experiment": "Formal experiment", "i_experiment": "Informal experiment", "activity": "Activity", "Investigation": "Investigation", "groupdiscussion": "Group discussion", "casestudy": "Case study", "project": "Project", }[child.attrib["type"]], ) ) pos = 1 while pos < len(child): if child[pos].tag == "section": sectionNode = child[pos] assert sectionNode[0].tag == "title" del child[pos] child.insert(pos, utils.create_node("para")) child[pos].append(utils.create_node("emphasis", text=sectionNode[0].text.strip())) child[pos][-1].attrib["effect"] = "bold" pos += 1 sectionChildren = sectionNode.getchildren() for i in range(1, len(sectionChildren)): child.insert(pos, sectionChildren[i]) pos += 1 else: pos += 1 childIndex += 1 elif child.tag == "worked_example": # <worked_example> <title/> <question/> <answer> ... <workstep> <title/> ... </workstep> </answer> </worked_example> child.tag = "example" newSubChildren = [] newSubChildren.append(utils.create_node("label", text="Worked example")) pos = 1 for subChild in child: if subChild.tag == "title": newSubChildren.append(subChild) elif subChild.tag == "question": newSubChildren.append(subChild) subChild.tag = "section" subChild.append(utils.create_node("title", text="Question")) elif subChild.tag == "answer": newSubChildren.append(subChild) subChild.tag = "section" subChild.append(utils.create_node("title", text="Answer")) for x in subChild: if x.tag == "workstep": x.tag = "section" childIndex += 1 elif child.tag == "note": child.insert( 0, utils.create_node( "label", text={"warning": "Warning", "tip": "Tip", "note": "Note", "aside": "Interesting Fact"}.get( child.attrib["type"], child.attrib["type"] ), ), ) childIndex += 1 elif child.tag == "math_identity": del element[childIndex] # Remove math_identity from DOM, still available as child ruleNode = utils.create_node("rule") ruleNode.attrib["type"] = "Identity" child.tag = "statement" ruleNode.append(child) element.insert(childIndex, ruleNode) childIndex += 1 elif child.tag == "nuclear_notation": namespace = "http://www.w3.org/1998/Math/MathML" mathNode = utils.create_node("math", namespace=namespace) mathNode.append(utils.create_node("msubsup", namespace=namespace)) mathNode[-1].append(utils.create_node("mo", namespace=namespace, text=u"\u200b")) mathNode[-1].append(utils.create_node("mn", namespace=namespace, text=child.find("atomic_number").text)) if child.find("mass_number") is not None: massNumber = child.find("mass_number").text else: massNumber = u"\u200b" mathNode[-1].append(utils.create_node("mn", namespace=namespace, text=massNumber)) mathNode.append(utils.create_node("mtext", namespace=namespace, text=child.find("symbol").text)) mathNode.tail = child.tail element[childIndex] = mathNode childIndex += 1 elif child.tag == "math_extension": child.tag = "note" titleNode = child.find("title") if titleNode is not None: titleNode.tag = "label" titleNode.text = u"Extension \u2014 " + titleNode.text.strip() else: child.insert(0, utils.create_node("label", text="Extension")) bodyNode = child.find("body") utils.etree_replace_with_node_list(child, bodyNode, bodyNode) childIndex += 1 elif child.tag == "section": # Check that it is not an activity section if child.getparent().tag != "activity": shortCodeNode = child.find("shortcode") if shortCodeNode is None: if (child.attrib.get("type") not in ["subsubsection", "subsubsubsection"]) and ( child.find("title").text.strip() != "Chapter summary" ): print 'WARNING: no shortcode for section "%s"' % child.find("title").text.strip() shortcode = "SHORTCODE" else: shortcode = None else: if (child.attrib.get("type") in ["subsubsection", "subsubsubsection"]) or ( child.find("title").text.strip() == "Chapter summary" ): print 'WARNING: section "%s" should not have a shortcode' % child.find("title").text.strip() shortcode = shortCodeNode.text.strip() child.remove(shortCodeNode) """ # Commented out so that shortcodes do not get displayed if shortcode is not None: titleNode = child.find('title') if len(titleNode) == 0: if titleNode.text is None: titleNode.text = '' titleNode.text += ' [' + shortcode + ']' else: if titleNode[-1].tail is None: titleNode[-1].tail = '' titleNode[-1].tail += ' [' + shortcode + ']' """ childIndex += 1 elif child.tag == "latex": if child.attrib.get("display", "inline") == "block": delimiters = "[]" else: delimiters = "()" if child.text is None: child.text = "" child.text = "\\" + delimiters[0] + child.text if len(child) > 0: if child[-1].text is None: child[-1].tail = "" child[-1].tail += "\\" + delimiters[1] else: child.text += "\\" + delimiters[1] utils.etree_replace_with_node_list(element, child, child) childIndex += len(child) elif child.tag in ["chem_compound", "spec_note"]: assert len(child) == 0, "<chem_compound> element not expected to have sub-elements." if child.text is None: child.text = "" child.text = child.text.strip() assert child.text != "", "<chem_compound> element must contain text." compoundText = child.text pos = 0 textOpen = False while pos < len(compoundText): if "a" <= compoundText[pos].lower() <= "z": if not textOpen: compoundText = compoundText[:pos] + r"\text{" + compoundText[pos:] textOpen = True pos += len(r"\text{") + 1 else: pos += 1 else: if textOpen: compoundText = compoundText[:pos] + "}" + compoundText[pos:] textOpen = False pos += 2 else: pos += 1 if textOpen: compoundText += "}" compoundXml = utils.xmlify(r"\(" + compoundText + r"\)") compoundDom = etree.fromstring(compoundXml[compoundXml.find("<formula ") : compoundXml.rfind("\n</p>")]) utils.etree_replace_with_node_list(element, child, compoundDom) childIndex += len(child) else: path = [child.tag] node = child while True: node = node.getparent() if node is None: break path.append(node.tag) path.reverse() namespaces = {"m": "http://www.w3.org/1998/Math/MathML"} valid = [ "emphasis", "para", "figure/type", "exercise/problem", "exercise/title", "exercise/shortcodes/entry/number", "exercise/shortcodes/entry/shortcode", "exercise/shortcodes/entry/url", "exercise/shortcodes/entry/todo-content", "list/item/label", "table/tgroup/tbody/row/entry", "table/tgroup/colspec", "definition/term", "definition/meaning", "sup", "sub", "m:mn", "m:mo", "m:mi", "m:msup", "m:mrow", "m:math", "m:mtable", "m:mtr", "m:mtd", "m:msub", "m:mfrac", "m:msqrt", "m:mspace", "m:mstyle", "m:mfenced", "m:mtext", "m:mroot", "m:mref", "m:msubsup", "m:munderover", "m:munder", "m:mover", "m:mphantom", "equation", "link", "quote", "rule/title", "rule/statement", "rule/proof", "section/title", "section/shortcode", "image/arguments", "image/src", "number/coeff", "number/exp", "number/base", "nuclear_notation/mass_number", "nuclear_notation/atomic_number", "nuclear_notation/symbol", "pspicture/code", "pspicture/usepackage", "tikzpicture/code", "video/title", "video/shortcode", "video/url", "video/width", "video/height", "worked_example/answer/workstep/title", "worked_example/question", "worked_example/title", "activity/title", "math_extension/title", "math_extension/body", "math_identity", "document/content/title", "document/content/content", "simulation/title", "simulation/shortcode", "simulation/url", "simulation/width", "simulation/height", "simulation/embed", "presentation/title", "presentation/url", "presentation/shortcode", "presentation/embed", "box", ] validSet = set([]) for entry in valid: entry = entry.split("/") for i in range(len(entry)): if ":" in entry[i]: entry[i] = entry[i].split(":") assert len(entry[i]) == 2 entry[i] = "{%s}%s" % (namespaces[entry[i][0]], entry[i][1]) validSet.add(tuple(entry[: i + 1])) valid = validSet passed = False for entry in valid: if tuple(path[-len(entry) :]) == entry: passed = True break if not passed: path = "/".join(path) for key, url in namespaces.iteritems(): path = path.replace("{%s}" % url, key + ":") LOGGER.info("Unhandled element: " + path) childIndex += 1
def traverse_dom_for_cnxml(self, element): # traverse every element in tree, find matching environments, transform for child in element: self.traverse_dom_for_cnxml(child) childIndex = 0 while childIndex < len(element): child = element[childIndex] if child.tag in ['video', 'simulation', 'presentation', 'box']: child.tag = 'todo-' + child.tag childIndex += 1 elif child.tag == 'image': # <image> <arguments/> <src/> </image> mediaNode = utils.create_node('media') mediaNode.append(utils.create_node('image')) mediaNode.attrib['alt'] = 'Image' urlNode = child.find('src') if urlNode is not None: mediaNode[0].attrib['src'] = urlNode.text.strip() else: mediaNode[0].attrib['src'] = '' mediaNode.tail = child.tail element[childIndex] = mediaNode childIndex += 1 elif child.tag == 'figure': typeNode = child.find('type') if typeNode is not None: typ = typeNode.text.strip() child.attrib['type'] = typ typeNode.tag = 'label' typeNode.text = {'figure': 'Figure', 'table': 'Table'}[typ] childIndex += 1 elif child.tag == 'caption': if (len(child) == 1) and (child[0].tag == 'para'): utils.etree_replace_with_node_list(child, child[0], child[0]) childIndex += 1 elif child.tag == 'activity': # <activity type="activity"><title/> <section><title/>...</section> </activity> child.tag = 'example' child.append(utils.create_node('label', text={ 'g_experiment': 'General experiment', 'f_experiment': 'Formal experiment', 'i_experiment': 'Informal experiment', 'activity': 'Activity', 'Investigation': 'Investigation', 'groupdiscussion': 'Group discussion', 'casestudy': 'Case study', 'project': 'Project'}[child.attrib['type']])) pos = 1 while pos < len(child): if child[pos].tag == 'section': sectionNode = child[pos] assert sectionNode[0].tag == 'title' del child[pos] child.insert(pos, utils.create_node('para')) child[pos].append(utils.create_node('emphasis', text=sectionNode[0].text.strip())) child[pos][-1].attrib['effect'] = 'bold' pos += 1 sectionChildren = sectionNode.getchildren() for i in range(1, len(sectionChildren)): child.insert(pos, sectionChildren[i]) pos += 1 else: pos += 1 childIndex += 1 elif child.tag == 'worked_example': # <worked_example> <title/> <question/> <answer> ... <workstep> <title/> ... </workstep> </answer> </worked_example> child.tag = 'example' newSubChildren = [] newSubChildren.append(utils.create_node('label', text="Worked example")) pos = 1 for subChild in child: if subChild.tag == 'title': newSubChildren.append(subChild) elif subChild.tag == 'question': newSubChildren.append(subChild) subChild.tag = 'section' subChild.append(utils.create_node('title', text='Question')) elif subChild.tag == 'answer': newSubChildren.append(subChild) subChild.tag = 'section' subChild.append(utils.create_node('title', text='Answer')) for x in subChild: if x.tag == 'workstep': x.tag = 'section' childIndex += 1 elif child.tag == 'note': child.insert(0, utils.create_node('label', text={ 'warning': 'Warning', 'tip': 'Tip', 'note': 'Note', 'aside': 'Interesting Fact'}.get(child.attrib['type'], child.attrib['type']))) childIndex += 1 elif child.tag == 'math_identity': del element[childIndex] # Remove math_identity from DOM, still available as child ruleNode = utils.create_node('rule') ruleNode.attrib['type'] = 'Identity' child.tag = 'statement' ruleNode.append(child) element.insert(childIndex, ruleNode) childIndex += 1 elif child.tag == 'nuclear_notation': namespace = 'http://www.w3.org/1998/Math/MathML' mathNode = utils.create_node('math', namespace=namespace) mathNode.append(utils.create_node('msubsup', namespace=namespace)) mathNode[-1].append(utils.create_node('mo', namespace=namespace, text=u'\u200b')) mathNode[-1].append(utils.create_node('mn', namespace=namespace, text=child.find('atomic_number').text)) if child.find('mass_number') is not None: massNumber = child.find('mass_number').text else: massNumber = u'\u200b' mathNode[-1].append(utils.create_node('mn', namespace=namespace, text=massNumber)) mathNode.append(utils.create_node('mtext', namespace=namespace, text=child.find('symbol').text)) mathNode.tail = child.tail element[childIndex] = mathNode childIndex += 1 elif child.tag == 'math_extension': child.tag = 'note' titleNode = child.find('title') if titleNode is not None: titleNode.tag = 'label' titleNode.text = u'Extension \u2014 ' + titleNode.text.strip() else: child.insert(0, utils.create_node('label', text='Extension')) bodyNode = child.find('body') utils.etree_replace_with_node_list(child, bodyNode, bodyNode) childIndex += 1 elif child.tag == 'section': # Check that it is not an activity section if child.getparent().tag != 'activity': shortCodeNode = child.find('shortcode') if shortCodeNode is None: if (child.attrib.get('type') not in ['subsubsection', 'subsubsubsection']) and (child.find('title').text.strip() != 'Chapter summary'): print 'WARNING: no shortcode for section "%s"'%child.find('title').text.strip() shortcode = 'SHORTCODE' else: shortcode = None else: if (child.attrib.get('type') in ['subsubsection', 'subsubsubsection']) or (child.find('title').text.strip() == 'Chapter summary'): print 'WARNING: section "%s" should not have a shortcode'%child.find('title').text.strip() shortcode = shortCodeNode.text.strip() child.remove(shortCodeNode) """ # Commented out so that shortcodes do not get displayed if shortcode is not None: titleNode = child.find('title') if len(titleNode) == 0: if titleNode.text is None: titleNode.text = '' titleNode.text += ' [' + shortcode + ']' else: if titleNode[-1].tail is None: titleNode[-1].tail = '' titleNode[-1].tail += ' [' + shortcode + ']' """ childIndex += 1 elif child.tag == 'latex': if child.attrib.get('display', 'inline') == 'block': delimiters = '[]' else: delimiters = '()' if child.text is None: child.text = '' child.text = '\\' + delimiters[0] + child.text if len(child) > 0: if child[-1].text is None: child[-1].tail = '' child[-1].tail += '\\' + delimiters[1] else: child.text += '\\' + delimiters[1] utils.etree_replace_with_node_list(element, child, child) childIndex += len(child) elif child.tag in ['chem_compound', 'spec_note']: assert len(child) == 0, "<chem_compound> element not expected to have sub-elements." if child.text is None: child.text = '' child.text = child.text.strip() assert child.text != '', "<chem_compound> element must contain text." compoundText = child.text pos = 0 textOpen = False while pos < len(compoundText): if 'a' <= compoundText[pos].lower() <= 'z': if not textOpen: compoundText = compoundText[:pos] + r'\text{' + compoundText[pos:] textOpen = True pos += len(r'\text{') + 1 else: pos += 1 else: if textOpen: compoundText = compoundText[:pos] + '}' + compoundText[pos:] textOpen = False pos += 2 else: pos += 1 if textOpen: compoundText += '}' compoundXml = utils.xmlify(r'\(' + compoundText + r'\)') compoundDom = etree.fromstring(compoundXml[compoundXml.find('<formula '):compoundXml.rfind('\n</p>')]) utils.etree_replace_with_node_list(element, child, compoundDom) childIndex += len(child) else: path = [child.tag] node = child while True: node = node.getparent() if node is None: break path.append(node.tag) path.reverse() namespaces = {'m': 'http://www.w3.org/1998/Math/MathML'} valid = [ 'emphasis', 'para', 'figure/type', 'exercise/problem', 'exercise/title', 'exercise/shortcodes/entry/number', 'exercise/shortcodes/entry/shortcode', 'exercise/shortcodes/entry/url', 'exercise/shortcodes/entry/todo-content', 'list/item/label', 'table/tgroup/tbody/row/entry', 'table/tgroup/colspec', 'definition/term', 'definition/meaning', 'sup', 'sub', 'm:mn', 'm:mo', 'm:mi', 'm:msup', 'm:mrow', 'm:math', 'm:mtable', 'm:mtr', 'm:mtd', 'm:msub', 'm:mfrac', 'm:msqrt', 'm:mspace', 'm:mstyle', 'm:mfenced', 'm:mtext', 'm:mroot', 'm:mref', 'm:msubsup', 'm:munderover', 'm:munder', 'm:mover', 'm:mphantom', 'equation', 'link', 'quote', 'rule/title', 'rule/statement', 'rule/proof', 'section/title', 'section/shortcode', 'image/arguments', 'image/src', 'number/coeff', 'number/exp', 'number/base', 'nuclear_notation/mass_number', 'nuclear_notation/atomic_number', 'nuclear_notation/symbol', 'pspicture/code', 'pspicture/usepackage', 'tikzpicture/code', 'video/title', 'video/shortcode', 'video/url', 'video/width', 'video/height', 'worked_example/answer/workstep/title', 'worked_example/question', 'worked_example/title', 'activity/title', 'math_extension/title', 'math_extension/body', 'math_identity', 'document/content/title', 'document/content/content', 'simulation/title', 'simulation/shortcode', 'simulation/url', 'simulation/width', 'simulation/height', 'simulation/embed', 'presentation/title', 'presentation/url', 'presentation/shortcode', 'presentation/embed', 'box', ] validSet = set([]) for entry in valid: entry = entry.split('/') for i in range(len(entry)): if ':' in entry[i]: entry[i] = entry[i].split(':') assert len(entry[i]) == 2 entry[i] = '{%s}%s'%(namespaces[entry[i][0]], entry[i][1]) validSet.add(tuple(entry[:i+1])) valid = validSet passed = False for entry in valid: if tuple(path[-len(entry):]) == entry: passed = True break if not passed: path = '/'.join(path) for key, url in namespaces.iteritems(): path = path.replace('{%s}'%url, key+':') LOGGER.info('Unhandled element: ' + path) childIndex += 1