[Docstring-checkins] CVS: dps/dps/transforms references.py,1.12,1.13
Status: Pre-Alpha
Brought to you by:
goodger
From: David G. <go...@us...> - 2002-04-13 17:06:21
|
Update of /cvsroot/docstring/dps/dps/transforms In directory usw-pr-cvs1:/tmp/cvs-serv15285/dps/dps/transforms Modified Files: references.py Log Message: Reworked reference resolution. Index: references.py =================================================================== RCS file: /cvsroot/docstring/dps/dps/transforms/references.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** references.py 16 Mar 2002 05:59:38 -0000 1.12 --- references.py 13 Apr 2002 17:06:18 -0000 1.13 *************** *** 23,129 **** class Hyperlinks(Transform): ! """ ! Resolve the various types of hyperlink targets and references. ! ! Shown in isolation, the following individual transforms are performed: ! ! 1. Anonymous references and targets:: ! ! <paragraph> ! <reference anonymous="1"> ! text ! <target anonymous="1"> ! ! Corresponding references and targets are assigned ids:: ! ! <paragraph> ! <reference anonymous="1" refid="id1"> ! text ! <target anonymous="1" id="id1"> ! ! 2. Chained targets:: ! ! <target id="id1" name="chained"> ! <target id="id2" name="external hyperlink" refuri="http://uri"> ! ! Attributes "refuri" and "refname" are migrated from the final concrete ! target up the chain of contiguous adjacent internal targets:: ! ! <target id="id1" name="chained" refuri="http://uri"> ! <target id="id2" name="external hyperlink" refuri="http://uri"> ! ! 3. a) Indirect targets:: ! ! <paragraph> ! <reference refname="indirect external"> ! indirect external ! <target id="id1" name="direct external" ! refuri="http://indirect"> ! <target id="id2" name="indirect external" ! refname="direct external"> ! ! Attributes "refuri" and "refname" are migrated back to all indirect ! targets from the final concrete target (i.e. not referring to ! another indirect target):: ! ! <paragraph> ! <reference refname="indirect external"> ! indirect external ! <target id="id1" name="direct external" ! refuri="http://indirect"> ! <target id="id2" name="indirect external" ! refuri="http://indirect"> ! ! If the "refuri" attribute is migrated, the preexisting "refname" ! attribute is dropped. This turns indirect external references into ! direct external references. ! ! b) Indirect internal references:: ! ! <target id="id1" name="final target"> ! <paragraph> ! <reference refname="indirect internal"> ! indirect internal ! <target id="id2" name="indirect internal 2" ! refname="final target"> ! <target id="id3" name="indirect internal" ! refname="indirect internal 2"> ! ! Targets which indirectly refer to an internal target become one-hop ! indirect (their "refname" attributes are directly set to the ! internal target's "name"). References which indirectly refer to an ! internal target become direct internal references:: ! ! <target id="id1" name="final target"> ! <paragraph> ! <reference refname="final target"> ! indirect internal ! <target id="id2" name="indirect internal 2" ! refname="final target"> ! <target id="id3" name="indirect internal" ! refname="final target"> ! ! 4. External references:: ! ! <paragraph> ! <reference refname="direct external"> ! direct external ! <target id="id1" name="direct external" refuri="http://direct"> ! ! The "refname" attribute is replaced by the direct "refuri" attribute:: ! ! <paragraph> ! <reference refuri="http://direct"> ! direct external ! <target id="id1" name="direct external" refuri="http://direct"> ! """ def transform(self): ! self.resolve_anonymous() self.resolve_chained_targets() self.resolve_indirect() ! self.resolve_external_references() def resolve_anonymous(self): if len(self.doctree.anonymous_refs) \ != len(self.doctree.anonymous_targets): --- 23,78 ---- class Hyperlinks(Transform): ! """Resolve the various types of hyperlink targets and references.""" def transform(self): ! stages = [] ! #stages.append('Beginning of references.Hyperlinks.transform()\n' + self.doctree.pformat()) self.resolve_chained_targets() + #stages.append('After references.Hyperlinks.resolve_chained_targets()\n' + self.doctree.pformat()) + self.resolve_anonymous() + #stages.append('After references.Hyperlinks.resolve_anonymous()\n' + self.doctree.pformat()) self.resolve_indirect() ! #stages.append('After references.Hyperlinks.resolve_indirect()\n' + self.doctree.pformat()) ! self.resolve_external_targets() ! #stages.append('After references.Hyperlinks.resolve_external_references()\n' + self.doctree.pformat()) ! self.resolve_internal_targets() ! #stages.append('After references.Hyperlinks.resolve_internal_references()\n' + self.doctree.pformat()) ! #import difflib ! #compare = difflib.Differ().compare ! #for i in range(len(stages) - 1): ! # print ''.join(compare(stages[i].splitlines(1), stages[i+1].splitlines(1))) ! ! def resolve_chained_targets(self): ! """ ! Attributes "refuri" and "refname" are migrated from the final direct ! target up the chain of contiguous adjacent internal targets, using ! `ChainedTargetResolver`. ! """ ! visitor = ChainedTargetResolver(self.doctree) ! self.doctree.walk(visitor) def resolve_anonymous(self): + """ + Link anonymous references to targets. Given:: + + <paragraph> + <reference anonymous="1"> + internal + <reference anonymous="1"> + external + <target anonymous="1" id="id1"> + <target anonymous="1" id="id2" refuri="http://external"> + + Corresponding references are linked via "refid" or resolved via + "refuri":: + + <paragraph> + <reference anonymous="1" refid="id1"> + text + <reference anonymous="1" refuri="http://external"> + external + <target anonymous="1" id="id1"> + <target anonymous="1" id="id2" refuri="http://external"> + """ if len(self.doctree.anonymous_refs) \ != len(self.doctree.anonymous_targets): *************** *** 133,248 **** len(self.doctree.anonymous_targets))) self.doctree.messages += msg return for i in range(len(self.doctree.anonymous_refs)): - name = '_:%s:_' % self.doctree.anonymous_start - self.doctree.anonymous_start += 1 ref = self.doctree.anonymous_refs[i] - ref['refname'] = name - self.doctree.note_refname(ref) target = self.doctree.anonymous_targets[i] ! target['name'] = name ! id = self.doctree.set_id(target) ! self.doctree.note_implicit_target(target, self.doctree) ! if target.hasattr('refname'): ! #ref['refname'] = target['refname'] ! self.doctree.note_indirect_target(target) ! elif target.hasattr('refuri'): ! #ref['refuri'] = target['refuri'] ! self.doctree.note_external_target(target) ! #else: ! # ref['refid'] = id ! ! def resolve_chained_targets(self): ! visitor = ChainedTargetResolver(self.doctree) ! self.doctree.walk(visitor) def resolve_indirect(self): ! for name, target in self.doctree.indirect_targets.items(): if not target.resolved: ! self.one_indirect_target(target) ! if target.hasattr('refname'): ! self.one_indirect_reference(target['name'], ! target['refname']) ! def one_indirect_target(self, target): ! name = target['name'] refname = target['refname'] if self.doctree.explicit_targets.has_key(refname): ! try: ! reftarget = self.doctree.explicit_targets[refname] ! except KeyError: ! self.nonexistent_indirect_target(name, refname, target) ! return ! if reftarget.hasattr('name'): ! if not reftarget.resolved and reftarget.hasattr('refname'): ! self.one_indirect_target(reftarget) # multiply indirect ! if reftarget.hasattr('refuri'): ! target['refuri'] = reftarget['refuri'] ! del target['refname'] ! self.doctree.note_external_target(target) ! elif reftarget.hasattr('refname'): ! target['refname'] = reftarget['refname'] ! #else: # @@@ ? ! # target['refid'] = reftarget['refid'] elif self.doctree.implicit_targets.has_key(refname): reftarget = self.doctree.implicit_targets[refname] try: ! target['refname'] = reftarget['name'] except KeyError: ! self.nonexistent_indirect_target(name, refname, target) return ! else: ! self.nonexistent_indirect_target(name, refname, target) ! return target.resolved = 1 ! def nonexistent_indirect_target(self, name, refname, target): ! if target.hasattr('anonymous'): ! naming = '(id="%s")' % target['id'] else: ! naming = '"%s"' % name msg = self.doctree.reporter.warning( 'Indirect hyperlink target %s refers to target "%s", ' ! 'which does not exist.' % (naming, refname)) self.doctree.messages += msg ! def one_indirect_reference(self, name, refname): ! try: ! reflist = self.doctree.refnames[name] ! except KeyError, instance: ! msg = self.doctree.reporter.info( ! 'Indirect hyperlink target "%s" is not referenced.' ! % name) ! self.doctree.messages += msg return ! for ref in self.doctree.refnames[name]: if ref.resolved: continue ! ref['refname'] = refname ref.resolved = 1 if isinstance(ref, nodes.target): ! self.one_indirect_reference(ref['name'], refname) ! def resolve_external_references(self): ! for name, target in self.doctree.external_targets.items(): if target.hasattr('refuri') and target.hasattr('name'): ! self.one_external_reference(name, target['refuri']) ! def one_external_reference(self, name, refuri): ! try: ! reflist = self.doctree.refnames[name] ! except KeyError, instance: ! msg = self.doctree.reporter.info( ! 'External hyperlink target "%s" is not referenced.' % name) ! self.doctree.messages += msg ! return ! for ref in self.doctree.refnames[name]: ! if ref.resolved: continue ! ref['refuri'] = refuri ! del ref['refname'] ! ref.resolved = 1 ! if isinstance(ref, nodes.target): ! self.one_external_reference(ref['name'], refuri) --- 82,345 ---- len(self.doctree.anonymous_targets))) self.doctree.messages += msg + msgid = self.doctree.set_id(msg) + for ref in self.doctree.anonymous_refs: + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.doctree.set_id(prb) + msg.add_backref(prbid) + ref.parent.replace(ref, prb) return for i in range(len(self.doctree.anonymous_refs)): ref = self.doctree.anonymous_refs[i] target = self.doctree.anonymous_targets[i] ! if target.hasattr('refuri'): ! ref['refuri'] = target['refuri'] ! ref.resolved = 1 ! else: ! ref['refid'] = target['id'] ! self.doctree.note_refid(ref) ! target.referenced = 1 def resolve_indirect(self): ! """ ! a) Indirect external references:: ! ! <paragraph> ! <reference refname="indirect external"> ! indirect external ! <target id="id1" name="direct external" ! refuri="http://indirect"> ! <target id="id2" name="indirect external" ! refname="direct external"> ! ! The "refuri" attribute is migrated back to all indirect targets from ! the final direct target (i.e. a target not referring to another ! indirect target):: ! ! <paragraph> ! <reference refname="indirect external"> ! indirect external ! <target id="id1" name="direct external" ! refuri="http://indirect"> ! <target id="id2" name="indirect external" ! refuri="http://indirect"> ! ! Once the attribute is migrated, the preexisting "refname" attribute ! is dropped. ! ! b) Indirect internal references:: ! ! <target id="id1" name="final target"> ! <paragraph> ! <reference refname="indirect internal"> ! indirect internal ! <target id="id2" name="indirect internal 2" ! refname="final target"> ! <target id="id3" name="indirect internal" ! refname="indirect internal 2"> ! ! Targets which indirectly refer to an internal target become one-hop ! indirect (their "refid" attributes are directly set to the internal ! target's "id"). References which indirectly refer to an internal ! target become direct internal references:: ! ! <target id="id1" name="final target"> ! <paragraph> ! <reference refid="id1"> ! indirect internal ! <target id="id2" name="indirect internal 2" refid="id1"> ! <target id="id3" name="indirect internal" refid="id1"> ! """ ! #import mypdb as pdb ! #pdb.set_trace() ! for target in self.doctree.indirect_targets: if not target.resolved: ! self.resolve_indirect_target(target) ! self.resolve_indirect_references(target) ! def resolve_indirect_target(self, target): refname = target['refname'] + reftarget = None if self.doctree.explicit_targets.has_key(refname): ! reftarget = self.doctree.explicit_targets[refname] elif self.doctree.implicit_targets.has_key(refname): reftarget = self.doctree.implicit_targets[refname] + if not reftarget: + self.nonexistent_indirect_target(target) + return + if isinstance(reftarget, nodes.target) \ + and not reftarget.resolved and reftarget.hasattr('refname'): + self.one_indirect_target(reftarget) # multiply indirect + if reftarget.hasattr('refuri'): + target['refuri'] = reftarget['refuri'] + if target.hasattr('name'): + self.doctree.note_external_target(target) + elif reftarget.hasattr('refid'): + target['refid'] = reftarget['refid'] + self.doctree.note_refid(target) + else: try: ! target['refid'] = reftarget['id'] ! self.doctree.note_refid(target) except KeyError: ! self.nonexistent_indirect_target(target) return ! del target['refname'] target.resolved = 1 + reftarget.referenced = 1 ! def nonexistent_indirect_target(self, target): ! naming = '' ! if target.hasattr('name'): ! naming = '"%s" ' % target['name'] ! reflist = self.doctree.refnames[target['name']] else: ! reflist = self.doctree.refnames[target['id']] ! naming += '(id="%s")' % target['id'] msg = self.doctree.reporter.warning( 'Indirect hyperlink target %s refers to target "%s", ' ! 'which does not exist.' % (naming, target['refname'])) self.doctree.messages += msg + msgid = self.doctree.set_id(msg) + for ref in reflist: + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.doctree.set_id(prb) + msg.add_backref(prbid) + ref.parent.replace(ref, prb) + target.resolved = 1 ! def resolve_indirect_references(self, target): ! if target.hasattr('refid'): ! attname = 'refid' ! call_if_named = 0 ! call_method = self.doctree.note_refid ! elif target.hasattr('refuri'): ! attname = 'refuri' ! call_if_named = 1 ! call_method = self.doctree.note_external_target ! else: return ! attval = target[attname] ! if target.hasattr('name'): ! name = target['name'] ! try: ! reflist = self.doctree.refnames[name] ! except KeyError, instance: ! if target.referenced: ! return ! msg = self.doctree.reporter.info( ! 'Indirect hyperlink target "%s" is not referenced.' ! % name) ! self.doctree.messages += msg ! target.referenced = 1 ! return ! delatt = 'refname' ! else: ! id = target['id'] ! try: ! reflist = self.doctree.refids[id] ! except KeyError, instance: ! if target.referenced: ! return ! msg = self.doctree.reporter.info( ! 'Indirect hyperlink target id="%s" is not referenced.' ! % id) ! self.doctree.messages += msg ! target.referenced = 1 ! return ! delatt = 'refid' ! for ref in reflist: if ref.resolved: continue ! del ref[delatt] ! ref[attname] = attval ! if not call_if_named or ref.hasattr('name'): ! call_method(ref) ref.resolved = 1 if isinstance(ref, nodes.target): ! self.resolve_indirect_references(ref) ! target.referenced = 1 ! def resolve_external_targets(self): ! """ ! Given:: ! ! <paragraph> ! <reference refname="direct external"> ! direct external ! <target id="id1" name="direct external" refuri="http://direct"> ! ! The "refname" attribute is replaced by the direct "refuri" attribute:: ! ! <paragraph> ! <reference refuri="http://direct"> ! direct external ! <target id="id1" name="direct external" refuri="http://direct"> ! """ ! for target in self.doctree.external_targets: if target.hasattr('refuri') and target.hasattr('name'): ! name = target['name'] ! refuri = target['refuri'] ! try: ! reflist = self.doctree.refnames[name] ! except KeyError, instance: ! if target.referenced: ! continue ! msg = self.doctree.reporter.info( ! 'External hyperlink target "%s" is not referenced.' ! % name) ! self.doctree.messages += msg ! target.referenced = 1 ! continue ! for ref in reflist: ! if ref.resolved: ! continue ! del ref['refname'] ! ref['refuri'] = refuri ! ref.resolved = 1 ! target.referenced = 1 ! def resolve_internal_targets(self): ! """ ! Given:: ! ! <paragraph> ! <reference refname="direct internal"> ! direct internal ! <target id="id1" name="direct internal"> ! ! The "refname" attribute is replaced by "refid" linking to the target's ! "id":: ! ! <paragraph> ! <reference refid="id1"> ! direct internal ! <target id="id1" name="direct internal"> ! """ ! for target in self.doctree.internal_targets: ! if target.hasattr('refuri') or target.hasattr('refid') \ ! or not target.hasattr('name'): continue ! name = target['name'] ! refid = target['id'] ! try: ! reflist = self.doctree.refnames[name] ! except KeyError, instance: ! if target.referenced: ! continue ! msg = self.doctree.reporter.info( ! 'Internal hyperlink target "%s" is not referenced.' ! % name) ! self.doctree.messages += msg ! target.referenced = 1 ! continue ! for ref in reflist: ! if ref.resolved: ! continue ! del ref['refname'] ! ref['refid'] = refid ! ref.resolved = 1 ! target.referenced = 1 *************** *** 253,257 **** "Chained targets" are multiple adjacent internal hyperlink targets which ! "point to" an external or indirect target. After the transform, all chained targets will effectively point to the same place. --- 350,354 ---- "Chained targets" are multiple adjacent internal hyperlink targets which ! "point to" an external or indirect target. After the transform, all chained targets will effectively point to the same place. *************** *** 259,284 **** <document> ! <target name="a"> ! <target name="b"> ! <target name="c" refuri="http://chained.external.targets"> ! <target name="d"> <paragraph> I'm known as "d". ! <target name="e"> ! <target name="f"> ! <target name="g" refname="d"> ``ChainedTargetResolver(doctree).walk()`` will transform the above into:: <document> ! <target name="a" refuri="http://chained.external.targets"> ! <target name="b" refuri="http://chained.external.targets"> ! <target name="c" refuri="http://chained.external.targets"> ! <target name="d"> <paragraph> I'm known as "d". ! <target name="e" refname="d"> ! <target name="f" refname="d"> ! <target name="g" refname="d"> """ --- 356,381 ---- <document> ! <target id="a" name="a"> ! <target id="b" name="b"> ! <target id="c" name="c" refuri="http://chained.external.targets"> ! <target id="d" name="d"> <paragraph> I'm known as "d". ! <target id="e" name="e"> ! <target id="id1"> ! <target id="f" name="f" refname="d"> ``ChainedTargetResolver(doctree).walk()`` will transform the above into:: <document> ! <target id="a" name="a" refuri="http://chained.external.targets"> ! <target id="b" name="b" refuri="http://chained.external.targets"> ! <target id="c" name="c" refuri="http://chained.external.targets"> ! <target id="d" name="d"> <paragraph> I'm known as "d". ! <target id="e" name="e" refname="d"> ! <target id="id1" refname="d"> ! <target id="f" name="f" refname="d"> """ *************** *** 288,312 **** def visit_target(self, node): if node.hasattr('refuri'): ! refuri = node['refuri'] ! index = node.parent.index(node) ! for i in range(index - 1, -1, -1): ! sibling = node.parent[i] ! if not isinstance(sibling, nodes.target) \ ! or sibling.hasattr('refuri') \ ! or sibling.hasattr('refname'): ! break ! sibling['refuri'] = refuri ! self.doctree.note_external_target(sibling) elif node.hasattr('refname'): ! refname = node['refname'] ! index = node.parent.index(node) ! for i in range(index - 1, -1, -1): ! sibling = node.parent[i] ! if not isinstance(sibling, nodes.target) \ ! or sibling.hasattr('refuri') \ ! or sibling.hasattr('refname'): ! break ! sibling['refname'] = refname ! self.doctree.note_indirect_target(sibling) --- 385,410 ---- def visit_target(self, node): if node.hasattr('refuri'): ! attname = 'refuri' ! call_if_named = self.doctree.note_external_target elif node.hasattr('refname'): ! attname = 'refname' ! call_if_named = self.doctree.note_indirect_target ! elif node.hasattr('refid'): ! attname = 'refid' ! call_if_named = None ! else: ! return ! attval = node[attname] ! index = node.parent.index(node) ! for i in range(index - 1, -1, -1): ! sibling = node.parent[i] ! if not isinstance(sibling, nodes.target) \ ! or sibling.hasattr('refuri') \ ! or sibling.hasattr('refname') \ ! or sibling.hasattr('refid'): ! break ! sibling[attname] = attval ! if sibling.hasattr('name') and call_if_named: ! call_if_named(sibling) *************** *** 314,318 **** """ ! Assign numbers and resolve links to autonumbered footnotes and references. Given the following ``doctree`` as input:: --- 412,417 ---- """ ! Assign numbers to autonumbered footnotes, and resolve links to footnotes, ! citations, and their references. Given the following ``doctree`` as input:: *************** *** 321,332 **** <paragraph> A labeled autonumbered footnote referece: ! <footnote_reference auto="1" refname="footnote"> <paragraph> An unlabeled autonumbered footnote referece: ! <footnote_reference auto="1"> ! <footnote auto="1"> <paragraph> Unlabeled autonumbered footnote. ! <footnote auto="1" name="footnote"> <paragraph> Labeled autonumbered footnote. --- 420,431 ---- <paragraph> A labeled autonumbered footnote referece: ! <footnote_reference auto="1" id="id1" refname="footnote"> <paragraph> An unlabeled autonumbered footnote referece: ! <footnote_reference auto="1" id="id2"> ! <footnote auto="1" id="id3"> <paragraph> Unlabeled autonumbered footnote. ! <footnote auto="1" id="footnote" name="footnote"> <paragraph> Labeled autonumbered footnote. *************** *** 343,358 **** <paragraph> A labeled autonumbered footnote referece: ! <footnote_reference auto="1" refname="footnote"> 2 <paragraph> An unlabeled autonumbered footnote referece: ! <footnote_reference auto="1" refname="1"> 1 ! <footnote auto="1" name="1"> <label> 1 <paragraph> Unlabeled autonumbered footnote. ! <footnote auto="1" name="footnote"> <label> 2 --- 442,457 ---- <paragraph> A labeled autonumbered footnote referece: ! <footnote_reference auto="1" id="id1" refid="footnote"> 2 <paragraph> An unlabeled autonumbered footnote referece: ! <footnote_reference auto="1" id="id2" refid="id3"> 1 ! <footnote auto="1" id="id3" backrefs="id2"> <label> 1 <paragraph> Unlabeled autonumbered footnote. ! <footnote auto="1" id="footnote" name="footnote" backrefs="id1"> <label> 2 *************** *** 362,369 **** Note that the footnotes are not in the same order as the references. ! The labels and reference text are added to the auto-numbered ! ``footnote`` and ``footnote_reference`` elements. The unlabeled ! auto-numbered footnote and reference are assigned name and refname ! attributes respectively, being the footnote number. After adding labels and reference text, the "auto" attributes can be --- 461,468 ---- Note that the footnotes are not in the same order as the references. ! The labels and reference text are added to the auto-numbered ``footnote`` ! and ``footnote_reference`` elements. Footnote elements are backlinked to ! their references via "refids" attributes. References are assigned "id" ! and "refid" attributes. After adding labels and reference text, the "auto" attributes can be *************** *** 394,412 **** self.autofootnote_labels = [] startnum = self.doctree.autofootnote_start ! self.number_footnotes() self.number_footnote_references(startnum) self.symbolize_footnotes() ! def number_footnotes(self): """ Assign numbers to autonumbered footnotes. ! For labeled footnotes, copy the number over to corresponding footnote ! references. """ for footnote in self.doctree.autofootnotes: while 1: ! label = str(self.doctree.autofootnote_start) ! self.doctree.autofootnote_start += 1 if not self.doctree.explicit_targets.has_key(label): break --- 493,512 ---- self.autofootnote_labels = [] startnum = self.doctree.autofootnote_start ! self.doctree.autofootnote_start = self.number_footnotes(startnum) self.number_footnote_references(startnum) self.symbolize_footnotes() + self.resolve_footnotes_and_citations() ! def number_footnotes(self, startnum): """ Assign numbers to autonumbered footnotes. ! For labeled autonumbered footnotes, copy the number over to ! corresponding footnote references. """ for footnote in self.doctree.autofootnotes: while 1: ! label = str(startnum) ! startnum += 1 if not self.doctree.explicit_targets.has_key(label): break *************** *** 418,421 **** --- 518,525 ---- for ref in self.doctree.footnote_refs.get(name, []): ref += nodes.Text(label) + ref.delattr('refname') + ref['refid'] = footnote['id'] + footnote.add_backref(ref['id']) + self.doctree.note_refid(ref) ref.resolved = 1 else: *************** *** 423,436 **** self.doctree.note_explicit_target(footnote, footnote) self.autofootnote_labels.append(label) def number_footnote_references(self, startnum): ! """Assign numbers to unlabeled autonumbered footnote references.""" i = 0 for ref in self.doctree.autofootnote_refs: ! if ref.resolved or ref.hasattr('refname'): continue try: ! ref += nodes.Text(self.autofootnote_labels[i]) ! ref['refname'] = self.autofootnote_labels[i] except IndexError: msg = self.doctree.reporter.error( --- 527,540 ---- self.doctree.note_explicit_target(footnote, footnote) self.autofootnote_labels.append(label) + return startnum def number_footnote_references(self, startnum): ! """Assign numbers to autonumbered footnote references.""" i = 0 for ref in self.doctree.autofootnote_refs: ! if ref.resolved or ref.hasattr('refid'): continue try: ! label = self.autofootnote_labels[i] except IndexError: msg = self.doctree.reporter.error( *************** *** 441,450 **** self.doctree.messages += msg for ref in self.doctree.autofootnote_refs[i:]: ! if not (ref.resolved or ref.hasattr('refname')): ! prb = nodes.problematic(ref.rawsource, ref.rawsource, ! refid=msgid) ! ref.parent.replace(ref, prb) ! # @@@ insert reference to each prb in msg? break ref.resolved = 1 i += 1 --- 545,561 ---- self.doctree.messages += msg for ref in self.doctree.autofootnote_refs[i:]: ! if ref.resolved or ref.hasattr('refname'): ! continue ! prb = nodes.problematic( ! ref.rawsource, ref.rawsource, refid=msgid) ! prbid = self.doctree.set_id(prb) ! msg.add_backref(prbid) ! ref.parent.replace(ref, prb) break + ref += nodes.Text(label) + footnote = self.doctree.explicit_targets[label] + ref['refid'] = footnote['id'] + self.doctree.note_refid(ref) + footnote.add_backref(ref['id']) ref.resolved = 1 i += 1 *************** *** 465,469 **** try: ref += nodes.Text(labels[i]) - ref['refid'] = self.doctree.symbol_footnotes[i]['id'] except IndexError: msg = self.doctree.reporter.error( --- 576,579 ---- *************** *** 473,485 **** self.doctree.messages += msg for ref in self.doctree.symbol_footnote_refs[i:]: ! if not (ref.resolved or ref.hasattr('refid')): ! prb = nodes.problematic(ref.rawsource, ref.rawsource, ! refid=msgid) ! ref.parent.replace(ref, prb) ! # @@@ insert reference to each prb in msg? break ! ref.resolved = 1 i += 1 class Substitutions(Transform): --- 583,627 ---- self.doctree.messages += msg for ref in self.doctree.symbol_footnote_refs[i:]: ! if ref.resolved or ref.hasattr('refid'): ! continue ! prb = nodes.problematic( ! ref.rawsource, ref.rawsource, refid=msgid) ! prbid = self.doctree.set_id(prb) ! msg.add_backref(prbid) ! ref.parent.replace(ref, prb) break ! footnote = self.doctree.symbol_footnotes[i] ! ref['refid'] = footnote['id'] ! self.doctree.note_refid(ref) ! footnote.add_backref(ref['id']) i += 1 + def resolve_footnotes_and_citations(self): + """ + Link manually-labeled footnotes and citations to/from their references. + """ + for footnote in self.doctree.footnotes: + label = footnote['name'] + if self.doctree.footnote_refs.has_key(label): + reflist = self.doctree.footnote_refs[label] + self.resolve_references(footnote, reflist) + for citation in self.doctree.citations: + label = citation['name'] + if self.doctree.citation_refs.has_key(label): + reflist = self.doctree.citation_refs[label] + self.resolve_references(citation, reflist) + + def resolve_references(self, note, reflist): + id = note['id'] + for ref in reflist: + if ref.resolved: + continue + ref.delattr('refname') + ref['refid'] = id + note.add_backref(ref['id']) + ref.resolved = 1 + note.resolved = 1 + + class Substitutions(Transform): *************** *** 522,528 **** self.doctree.messages += msg prb = nodes.problematic( ! ref.rawsource, '', refid=msgid, *ref.getchildren()) prbid = self.doctree.set_id(prb) ref.parent.replace(ref, prb) - msg['refid'] = prbid self.doctree.substitution_refs = None # release replaced references --- 664,670 ---- self.doctree.messages += msg prb = nodes.problematic( ! ref.rawsource, ref.rawsource, refid=msgid) prbid = self.doctree.set_id(prb) + msg.add_backref(prbid) ref.parent.replace(ref, prb) self.doctree.substitution_refs = None # release replaced references |