Skip to content
This repository
Browse code

Added the patch required for anolis

  • Loading branch information...
commit 0664f7aff8ab854cb6168357afdd6bf6cb4a31e3 1 parent 4bd1dcb
Ben Schwarz authored

Showing 1 changed file with 427 additions and 0 deletions. Show diff stats Hide diff stats

  1. +427 0 patch.anolis
427 patch.anolis
... ... @@ -0,0 +1,427 @@
  1 +diff -r 16550726fd0d anolis
  2 +--- a/anolis Sun Aug 30 16:53:19 2009 -0500
  3 ++++ b/anolis Sun Aug 22 21:32:00 2010 +0900
  4 +@@ -70,10 +70,10 @@
  5 +
  6 + def getOptParser():
  7 + def enable(option, opt_str, value, parser, *args, **kwargs):
  8 +- parser.values.processes.add(value)
  9 ++ parser.values.processes.append(value)
  10 +
  11 + def disable(option, opt_str, value, parser, *args, **kwargs):
  12 +- parser.values.processes.discard(value)
  13 ++ parser.values.processes.remove(value)
  14 +
  15 + parser = OptionParser(usage = __doc__, version="%prog 1.1dev")
  16 +
  17 +diff -r 16550726fd0d anolislib/processes/filter.py
  18 +--- a/anolislib/processes/filter.py Sun Aug 30 16:53:19 2009 -0500
  19 ++++ b/anolislib/processes/filter.py Sun Aug 22 21:32:00 2010 +0900
  20 +@@ -5,23 +5,4 @@
  21 + return
  22 + selector = cssselect.CSSSelector(kwargs["filter"])
  23 + for element in selector(ElementTree.getroot()):
  24 +- remove(element)
  25 +-
  26 +-def remove(element):
  27 +- if element.tail:
  28 +- if element.getprevious() is not None:
  29 +- target = element.getprevious()
  30 +- if target.tail:
  31 +- target.tail += element.tail
  32 +- else:
  33 +- target.tail = element.tail
  34 +- else:
  35 +- target = element.getparent()
  36 +- if target.text:
  37 +- target.text += element.text
  38 +- else:
  39 +- target.text = element.text
  40 +-
  41 +- element.getparent().remove(element)
  42 +-
  43 +-
  44 ++ element.drop_tree()
  45 +diff -r 16550726fd0d anolislib/processes/terms.py
  46 +--- /dev/null Thu Jan 01 00:00:00 1970 +0000
  47 ++++ b/anolislib/processes/terms.py Sun Aug 22 21:32:00 2010 +0900
  48 +@@ -0,0 +1,379 @@
  49 ++# coding=UTF-8
  50 ++# Copyright (c) 2010 Michael(tm) Smith
  51 ++#
  52 ++# Permission is hereby granted, free of charge, to any person obtaining a copy
  53 ++# of this software and associated documentation files (the "Software"), to deal
  54 ++# in the Software without restriction, including without limitation the rights
  55 ++# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  56 ++# copies of the Software, and to permit persons to whom the Software is
  57 ++# furnished to do so, subject to the following conditions:
  58 ++#
  59 ++# The above copyright notice and this permission notice shall be included in
  60 ++# all copies or substantial portions of the Software.
  61 ++#
  62 ++# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  63 ++# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  64 ++# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  65 ++# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  66 ++# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  67 ++# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  68 ++# THE SOFTWARE.
  69 ++
  70 ++import re
  71 ++
  72 ++from lxml import etree
  73 ++from copy import deepcopy
  74 ++
  75 ++from anolislib import utils
  76 ++
  77 ++class terms(object):
  78 ++ """Build and add an index of terms."""
  79 ++
  80 ++ terms = None
  81 ++
  82 ++ def __init__(self, ElementTree, **kwargs):
  83 ++ self.terms = etree.Element(u"div",{u"class": "index-of-terms"})
  84 ++ self.buildTerms(ElementTree, **kwargs)
  85 ++ self.addTerms(ElementTree, **kwargs)
  86 ++
  87 ++ def buildTerms(self, ElementTree, w3c_compat=False, **kwargs):
  88 ++ self.terms.text = "\n"
  89 ++ # make a list of all the defining instances of "terms" in the document
  90 ++ # -- <dfn> elements
  91 ++ dfnList = ElementTree.findall("//dfn")
  92 ++ if dfnList:
  93 ++ indexNavTop = etree.Element(u"div",{u"class": "index-nav", u"id": "index-terms_top"})
  94 ++ indexNavTop.text = "\n"
  95 ++ indexNavTop.tail = "\n"
  96 ++ indexNavHelpers = {"top": indexNavTop}
  97 ++ self.terms.append(indexNavHelpers["top"])
  98 ++ termFirstLetter = None
  99 ++ prevTermFirstLetter = None
  100 ++ firstLetters = ["top"]
  101 ++ # sort the list of <dfn> terms by the lowercase value of the DOM
  102 ++ # textContent of the <dfn> element (concantentation of the <dfn>
  103 ++ # text nodes and that of any of its descendant elements)
  104 ++ dfnList.sort(key=lambda dfn: dfn.text_content().lower())
  105 ++ for dfn in dfnList:
  106 ++ # we don't need the tail, so copy the <dfn> and drop the tail
  107 ++ term = deepcopy(dfn)
  108 ++ term.tail = None
  109 ++ termID = None
  110 ++ dfnHasID = False
  111 ++ if dfn.get("id"):
  112 ++ # if this <dfn> itself has an id, we'll use it as part of the
  113 ++ # id on the index entry for this term
  114 ++ termID = dfn.get("id")
  115 ++ dfnHasID = True
  116 ++ elif dfn.getparent().get("id"):
  117 ++ # if this <dfn> itself has no id, use the id of its parent
  118 ++ # node as the id on the index entry for this term, with or
  119 ++ termID = dfn.getparent().get("id")
  120 ++ # if we found an id, then create an index entry for this <dfn>
  121 ++ # term; otherwise, do nothing further
  122 ++ if termID:
  123 ++ indexEntry = etree.Element(u"dl")
  124 ++ # we want to give this index entry an id attribute based on
  125 ++ # the <dfn> or parent of a <dfn> we got the id-attribute
  126 ++ # value from earlier; but, if this <dfn> has no id attribute
  127 ++ # and has any sibling <dfn>s that also lack id attributes,
  128 ++ # we need to further qualify the id attribute here to make
  129 ++ # it unique
  130 ++ dfnSiblings = int(dfn.xpath("count(preceding-sibling::dfn[not(@id)])"))
  131 ++ if not dfnHasID and dfnSiblings > 0:
  132 ++ indexEntry = etree.Element(u"dl",{u"id": termID+"_"+str(dfnSiblings)+"_index"})
  133 ++ else:
  134 ++ indexEntry = etree.Element(u"dl",{u"id": termID+"_index"})
  135 ++ indexEntry.text = "\n"
  136 ++ # termName is container of the name of the term as it appears in the index
  137 ++ termName = etree.Element(u"dt")
  138 ++ if "id" in term.attrib:
  139 ++ del term.attrib["id"]
  140 ++ term.tag = "span"
  141 ++ term.tail = "\n"
  142 ++ termName.append(term);
  143 ++ termName.tail= "\n"
  144 ++ indexEntry.append(termName)
  145 ++ # normalize the text content of each <dfn> in the document
  146 ++ # and then normalize the text content of this <dfn>, then
  147 ++ # do a case-insensitive comparison of them and count how
  148 ++ # many matches we have
  149 ++ expr = "count(//dfn\
  150 ++ [normalize-space(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'))\
  151 ++ =normalize-space(translate($content,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'))])"
  152 ++ if ElementTree.xpath(expr, content = term.text_content()) > 1:
  153 ++ # we have more than one <dfn> in the document whose
  154 ++ # content is a case-insensitive match for the
  155 ++ # textContent of this <dfn>; so, we attempt to
  156 ++ # disambiguate them by copying the parent node of the
  157 ++ # <dfn> and including that in our output as an excerpt,
  158 ++ # to provide the context for the term
  159 ++ dfnContext = etree.Element(u"dd",{u"class": u"dfn-excerpt"})
  160 ++ dfnContext.text = "\n"
  161 ++ dfnContext.tail = "\n"
  162 ++ dfnParentNode = deepcopy(dfn.getparent())
  163 ++ # if length of the parent node isn't greater than 1,
  164 ++ # then the <dfn> is the only child node of its parent,
  165 ++ # and so there is no useful context we can provide, so
  166 ++ # we do nothing. Also, if the parent node is an h1-h6
  167 ++ # heading, we are already listing it in the entry, to
  168 ++ # it'd be redundant to be it here too, so we don't
  169 ++ if len(dfnParentNode) > 1 and not re.match("^[hH][1-6]$",dfnParentNode.tag):
  170 ++ # we just drop all of the text in this parent up to
  171 ++ # the first child element, because it's often just
  172 ++ # part of phrase like "The foo attribute" or
  173 ++ # something, and we don't need that. But, after we
  174 ++ # drop it, we don't want the node to end up starting
  175 ++ # with no next at all (because it looks odd in our
  176 ++ # output), so we replace it with some characters to
  177 ++ # indicate that there's something been ellided
  178 ++ if not dfnParentNode[0].tag == "dfn":
  179 ++ dfnParentNode.text = "*** "
  180 ++ # ...except for the case where we know our current
  181 ++ # dfn is the first child element, and then we deal
  182 ++ # with handling of that a little further down
  183 ++ else:
  184 ++ dfnParentNode.text = ""
  185 ++ dfnParentNode.tag = "span"
  186 ++ # remove ID so that we don't duplicate it
  187 ++ if "id" in dfnParentNode.attrib:
  188 ++ del dfnParentNode.attrib["id"]
  189 ++ descendants = dfnParentNode.xpath(".//*[self::dfn or @id]")
  190 ++ for descendant in descendants:
  191 ++ if descendant.tag == "dfn":
  192 ++ descendant.tag = "span"
  193 ++ if "id" in descendant.attrib:
  194 ++ del descendant.attrib["id"]
  195 ++ # if the text content of this descendant is the
  196 ++ # same as the text content of the term, then we
  197 ++ # don't want to repeat it, so instead we
  198 ++ # replace it with ellipses
  199 ++ if descendant.text_content().lower() == term.text_content().lower():
  200 ++ tail = ""
  201 ++ if descendant.tail is not None:
  202 ++ tail = descendant.tail
  203 ++ # drop any children this element might have,
  204 ++ # and just put ellipsis in place of it
  205 ++ descendant.clear()
  206 ++ descendant.text = "..."+tail
  207 ++ elif descendant == descendants[0]:
  208 ++ # if we get here it means that the first dfn
  209 ++ # child of this parent node is _not_ our
  210 ++ # current dfn, so we use some alternative
  211 ++ # characters (other than ellipses) to
  212 ++ # indicate that we've ellided something
  213 ++ dfnParentNode.text = "*** "
  214 ++ dfnContext.append(dfnParentNode)
  215 ++ indexEntry.append(dfnContext)
  216 ++ # we need a first letter so that we can build navigational
  217 ++ # links for the alphabetic nav bars injected into the index
  218 ++ termFirstLetter = term.text_content()[0].upper()
  219 ++ if termFirstLetter != prevTermFirstLetter and termFirstLetter.isalpha():
  220 ++ firstLetters.append(termFirstLetter)
  221 ++ indexNavHelpers[termFirstLetter] = etree.Element(u"div",{u"class": "index-nav", u"id": "index-terms_"+termFirstLetter})
  222 ++ prevTermFirstLetter = termFirstLetter
  223 ++ self.terms.append(indexNavHelpers[termFirstLetter])
  224 ++ # #########################################################
  225 ++ # make a list of all the instances of terms in the document
  226 ++ # that are hyperlinked references back to the <dfn> term
  227 ++ # that is the defining instance of this term, as well as
  228 ++ # the <dfn> defining instance itself
  229 ++ # #########################################################
  230 ++ instanceList = ElementTree.xpath("//a[substring-after(@href,'#')=$targetID]|//*[@id=$targetID]", targetID = termID)
  231 ++ if instanceList:
  232 ++ instanceItem = None
  233 ++ lastLinkToHeading = None
  234 ++ lastInstanceItem = None
  235 ++ for instance in instanceList:
  236 ++ # each of these term instances is an <a> hyperlink
  237 ++ # without an id attribute, but we need each to have
  238 ++ # an id attribute so that we can link back to it
  239 ++ # from the index of terms; so, create an id for each
  240 ++ instanceID = utils.generateID(instance, **kwargs)
  241 ++ instance.set(u"id",instanceID)
  242 ++ # make a link that's a copy of the node of the h1-h6
  243 ++ # heading for the section that contains this
  244 ++ # instance hyperlink
  245 ++ linkToHeading = self.getAncestorHeadingLink(instance, instanceID)
  246 ++ if not instance.tag == u"a":
  247 ++ linkToHeading.set(u"class","dfn-ref")
  248 ++ # if this heading is not the same as one that we've
  249 ++ # already added to the index entry for this term,
  250 ++ # then process the heading
  251 ++ if lastLinkToHeading is None or linkToHeading.text_content() != lastLinkToHeading.text_content():
  252 ++ instanceItem = etree.Element(u"dd")
  253 ++ instanceItem.text = "\n"
  254 ++ lastLinkToHeading = linkToHeading
  255 ++ n = 1
  256 ++ # we wait to add the item for the previous
  257 ++ # instance at this point because we need to
  258 ++ # delay adding in order to see if for this
  259 ++ # instance there are multiple references to the
  260 ++ # same ancestor heading (if there are, we append
  261 ++ # link numbers to them, instead of repeating the
  262 ++ # heading; see below)
  263 ++ if lastInstanceItem is not None:
  264 ++ #print(etree.tostring(lastInstanceItem,method="text"))
  265 ++ indexEntry.append(lastInstanceItem)
  266 ++ lastInstanceItem = instanceItem
  267 ++ linkToHeading.tail = "\n"
  268 ++ instanceItem.append(linkToHeading)
  269 ++ instanceItem.tail = "\n"
  270 ++ # otherwise, this heading is the same as one that
  271 ++ # we've already added to the index entry for this
  272 ++ # term; so instead of reprocessing the heading, we
  273 ++ # just append one or more link numbers to it
  274 ++ else:
  275 ++ n += 1
  276 ++ counterLink = etree.Element(u"a",{u"href": "#"+instanceID, u"class": "index-counter"})
  277 ++ if not instance.tag == u"a":
  278 ++ counterLink.set(u"class","dfn-ref")
  279 ++ else:
  280 ++ counterLink.set(u"class","index-counter")
  281 ++ counterLink.text = "("+str(n)+")"
  282 ++ counterLink.tail = "\n"
  283 ++ instanceItem.append(counterLink)
  284 ++ # if the value of our n counter is still at 1 at
  285 ++ # this point, it means the document contains only
  286 ++ # one instance of a reference this term, so we need
  287 ++ # to add that instance now
  288 ++ if n == 1:
  289 ++ indexEntry.append(instanceItem)
  290 ++ if not len(instanceList) > 1:
  291 ++ # if we don't have more than one item in this list, it
  292 ++ # means the <dfn> defining instance is the only item in
  293 ++ # the list, and the document contains no hyperlinked
  294 ++ # references back to that defining instance at all, so
  295 ++ # we need to set a flag to indicate that
  296 ++ indexEntry.set(u"class","has-norefs")
  297 ++ self.terms.append(indexEntry)
  298 ++ indexEntry.tail = "\n"
  299 ++ # ######################################################################
  300 ++ # inject some alphabetic nav hyperlink bars into the index, strictly
  301 ++ # for convenience purposes
  302 ++ # ######################################################################
  303 ++ navLetters = etree.Element(u"p")
  304 ++ navLetters.text = "\n"
  305 ++ navLetters.tail = "\n"
  306 ++ navLettersClones = {}
  307 ++ # reverse the letters list so that we can just pop off it
  308 ++ firstLetters.append("end")
  309 ++ firstLetters.reverse()
  310 ++ while(firstLetters):
  311 ++ letter = firstLetters.pop()
  312 ++ navLetter = etree.Element(u"a",{u"href": "#index-terms_"+letter})
  313 ++ navLetter.text = letter
  314 ++ navLetter.tail = "\n"
  315 ++ navLetters.append(navLetter)
  316 ++ for key, navNode in indexNavHelpers.items():
  317 ++ # this seems really hacky... but we need some way to manage multiple
  318 ++ # copies of the sets of nav hyperlink letters we inject into the
  319 ++ # index; otherwise, how to do it without just moving a single node
  320 ++ # around instead of copying it...
  321 ++ navLettersClones[key] = deepcopy(navLetters)
  322 ++ navNode.text = "\n"
  323 ++ navNode.append(navLettersClones[key])
  324 ++ navNode.tail = "\n"
  325 ++ navLettersEnd = deepcopy(navLetters)
  326 ++ indexNavEnd = etree.Element(u"div",{u"class": "index-nav", u"id": "index-terms_end"})
  327 ++ indexNavEnd.text = "\n"
  328 ++ indexNavEnd.tail = "\n"
  329 ++ indexNavEnd.append(navLettersEnd)
  330 ++ indexNavHelpers = {"end": indexNavEnd}
  331 ++ self.terms.append(indexNavHelpers["end"])
  332 ++ self.terms.tail = "\n"
  333 ++
  334 ++ def getAncestorHeadingLink(self, descendantNode, id):
  335 ++ """ Given a node, return a link to the heading for the section that contains it."""
  336 ++ node = descendantNode
  337 ++ while (node is not None):
  338 ++ if isinstance(node.tag,str) and re.match("^[hH][1-6]$",node.tag):
  339 ++ # we need a copy of this heading rather than the original node
  340 ++ headingLink = deepcopy(node)
  341 ++ # turn this h1-h6 heading copy into <a> hyperlink back to the
  342 ++ # location of the target node
  343 ++ headingLink.tag = "a"
  344 ++ headingLink.set(u"href","#"+id)
  345 ++ # this is a copy of an h1-h6 heading that may have had an id
  346 ++ # attribute; we don't want to duplicate the id, so drop it
  347 ++ if "id" in headingLink.attrib:
  348 ++ del headingLink.attrib["id"]
  349 ++ # some headings may contain descendants that are <a> links or
  350 ++ # <dfn>s, and/or that have id attributeds
  351 ++ embeddedLinks = headingLink.xpath(".//*[self::dfn or @href or @id]")
  352 ++ # we have taken a copy of what was a heading and transformed it
  353 ++ # into a hyperlink, and because it is a hyperlink, we now do not
  354 ++ # want it to itself contain descendant <a> links, nor any <dfn>s,
  355 ++ # so we transform those descendants into <span>s
  356 ++ for descendant in embeddedLinks:
  357 ++ if descendant.tag == "a" or descendant.tag == "dfn":
  358 ++ descendant.tag = "span"
  359 ++ # we need to remove any @href attributes left over in any
  360 ++ # descendants that we were <a> links
  361 ++ if "href" in descendant.attrib:
  362 ++ del descendant.attrib["href"]
  363 ++ # this descendant might be an <a> element that we added an
  364 ++ # id attribute to earlier and/or some other element with an ia
  365 ++ # attribute ; but we don't want to duplicate the id attributes
  366 ++ # here, so drop any id attribute we find
  367 ++ if "id" in descendant.attrib:
  368 ++ del descendant.attrib["id"]
  369 ++ return headingLink
  370 ++ elif node.getprevious() == None:
  371 ++ node = node.getparent()
  372 ++ else:
  373 ++ node = node.getprevious()
  374 ++ # note from MikeSmith: dunno the purpose of the following; just
  375 ++ # ported it over as-is from Hixie's dfn.js because it's there
  376 ++ if isinstance(node.tag,str) and node.get("class") == "impl":
  377 ++ node = xpath("node()[last()]")
  378 ++ return None
  379 ++
  380 ++ def addTerms(self, ElementTree, **kwargs):
  381 ++ to_remove = set()
  382 ++ in_terms = False
  383 ++ for node in ElementTree.iter():
  384 ++ if in_terms:
  385 ++ if node.tag is etree.Comment and \
  386 ++ node.text.strip(utils.spaceCharacters) == u"end-index-terms":
  387 ++ if node.getparent() is not terms_parent:
  388 ++ raise DifferentParentException(u"begin-index-terms and end-index-terms have different parents")
  389 ++ in_terms = False
  390 ++ else:
  391 ++ to_remove.add(node)
  392 ++ elif node.tag is etree.Comment:
  393 ++ if node.text.strip(utils.spaceCharacters) == u"begin-index-terms":
  394 ++ terms_parent = node.getparent()
  395 ++ in_terms = True
  396 ++ node.tail = None
  397 ++ node.addnext(deepcopy(self.terms))
  398 ++ self.indentNode(node.getnext(), 0, **kwargs)
  399 ++ elif node.text.strip(utils.spaceCharacters) == u"index-terms":
  400 ++ node.addprevious(etree.Comment(u"begin-index-terms"))
  401 ++ self.indentNode(node.getprevious(), 0, **kwargs)
  402 ++ node.addprevious(deepcopy(self.terms))
  403 ++ self.indentNode(node.getprevious(), 0, **kwargs)
  404 ++ node.addprevious(etree.Comment(u"end-index-terms"))
  405 ++ self.indentNode(node.getprevious(), 0, **kwargs)
  406 ++ node.getprevious().tail = node.tail
  407 ++ to_remove.add(node)
  408 ++ for node in to_remove:
  409 ++ node.getparent().remove(node)
  410 ++
  411 ++ def indentNode(self, node, indent=0, newline_char=u"\n", indent_char=u" ",
  412 ++ **kwargs):
  413 ++ whitespace = newline_char + indent_char * indent
  414 ++ if node.getprevious() is not None:
  415 ++ if node.getprevious().tail is None:
  416 ++ node.getprevious().tail = whitespace
  417 ++ else:
  418 ++ node.getprevious().tail += whitespace
  419 ++ else:
  420 ++ if node.getparent().text is None:
  421 ++ node.getparent().text = whitespace
  422 ++ else:
  423 ++ node.getparent().text += whitespace
  424 ++
  425 ++class DifferentParentException(utils.AnolisException):
  426 ++ """begin-index-terms and end-index-terms do not have the same parent."""
  427 ++ pass

0 comments on commit 0664f7a

Please sign in to comment.
Something went wrong with that request. Please try again.