6.14.7.2.6. Identifier Cross references

This is a bit hacky. When a tangler calls 'set_fc_anchor' with a file name and line number, an anchor with the name
  original_file_name + ':' + str(original_lineno)
is generated. Tanglers which call this function supply the original source file name and line number (not the file and line being written to).

Tanglers generate an entry for the identifier occurence which contains both the original source file and line number, and the output code file and line number.

The cross reference table the html weaver generates displays the output code file and line number (not the orginal file and line number), but it generates a reference of the form

  '#' + original_file_name + ':' + str(original_lineno)
using the original file name and line number.

The stacking weaver must trap calls to 'identifier_reference' because the hyperlinks the child weaver charged with generating this table would fail to refer to the specific html file containing the anchor. Instead, the stacking weaver must build the table.

To do that, the stacking weaver must know in which html child document the reference was generated so it can generate a hyperlink of the form:

  childname + '#' + original_file_name + ':' + str(original_lineno)
Unfortunately, the ids dictionary in the global frame currently being used to hold identifier cross references on a document wide basis, does not have this information available. It wouldn't make sense either, the information in that table is generated by tanglers, and has nothing to do with the weaver.

Therefore, the stacking weaver must _also_ intercept calls to 'set_fc_anchor', and create an entry in a dictionary keyed by the original filename and original line number, which tells in which html file the anchor was set: the stacking weaver knows that!

Comienzo python section to interscript/weavers/web.py[8 /8 ] Previo Primero
   633: #line 788 "web_weaver.ipk"
   634:   def mk_identref(self,filename,target):
   635:     ids = self.master.ids
   636:     if len(ids) == 0:
   637:       ids = self.pass_frame.ids
   638:     if len(ids) == 0: return 0
   639:     sink = named_file_sink(
   640:       self.pass_frame,
   641:       self.basedir+filename,
   642:       self.master.weaver_prefix,
   643:       eol=self.eol)
   644:     self.mk_head(sink)
   645:     w = sink.writeline
   646:     w ('<BODY LANG="'+self.language+'">')
   647: 
   648:     w('<H1>Index of Identifiers</H1>')
   649:     self.print_table(ids,sink)
   650: 
   651:     w('</BODY>')
   652:     w('</HTML>')
   653:     return 1
   654: 
   655:   def mk_sectionref(self,filename,target):
   656:     dict = self.pass_frame.section_index
   657:     if len(dict) == 0: return 0
   658:     sink = named_file_sink(
   659:       self.pass_frame,
   660:       self.basedir+filename,
   661:       self.master.weaver_prefix,
   662:       eol=self.eol)
   663:     self.mk_head(sink)
   664:     w = sink.writeline
   665:     w ('<BODY LANG="'+self.language+'">')
   666: 
   667:     w('<H1>Index of Sections</H1>')
   668:     keys = dict.keys()
   669:     keys.sort()
   670:     w = sink.writeline
   671:     w('<TABLE COLS="1" BORDER="1" CELLPADDING="2">')
   672:     for k in keys:
   673:       w('<TR><TD VALIGN="Top"><CODE> '+k+' </CODE>: ')
   674:       nsections = len(dict[k])
   675:       for i in range(nsections):
   676:         name = k + '['+str(i+1)+']'
   677:         anchor = '<A HREF="'+self.get_anchor(name)+\
   678:           '" TARGET="'+target+'">'+str(i+1)+'</A>'
   679:         w(anchor+' ')
   680:       w('</TD></TR>')
   681:     w('</TABLE>')
   682:     w('</BODY>')
   683:     w('</HTML>')
   684:     return 1
   685: 
   686:   def mk_classref(self,filename,target):
   687:     ids = self.master.classes
   688:     if len(ids) == 0:
   689:       ids = self.pass_frame.classes
   690:     if len(ids)==0: return 0
   691:     sink = named_file_sink(
   692:       self.pass_frame,
   693:       self.basedir+filename,
   694:       self.master.weaver_prefix,
   695:       eol=self.eol)
   696:     w = sink.writeline
   697:     self.mk_head(sink)
   698:     w ('<BODY LANG="'+self.language+'">')
   699: 
   700:     w('<H1>Index of Classes</H1>')
   701:     self.print_table(ids,sink)
   702:     w('</BODY>')
   703:     w('</HTML>')
   704:     return 1
   705: 
   706:   def mk_funcref(self,filename,target):
   707:     ids = self.master.functions
   708:     if len(ids) == 0:
   709:       ids = self.pass_frame.functions
   710:     if len(ids) ==0: return 0
   711:     sink = named_file_sink(
   712:       self.pass_frame,
   713:       self.basedir+filename,
   714:       self.master.weaver_prefix,
   715:       eol=self.eol)
   716:     w = sink.writeline
   717:     self.mk_head(sink)
   718:     w ('<BODY LANG="'+self.language+'">')
   719: 
   720:     w('<H1>Index of Functions</H1>')
   721:     self.print_table(ids,sink)
   722: 
   723:     w('</BODY>')
   724:     w('</HTML>')
   725:     return 1
   726: 
   727:   def mk_sourceref(self,filename,target):
   728:     data = self.master.include_files
   729:     if not data:
   730:       data = self.pass_frame.include_files
   731:     if len(data) == 0: return 0
   732:     sink = named_file_sink(
   733:       self.pass_frame,
   734:       self.basedir+filename,
   735:       self.master.weaver_prefix,
   736:       eol=self.eol)
   737:     w = sink.writeline
   738:     self.mk_head(sink)
   739:     w ('<BODY LANG="'+self.language+'">')
   740: 
   741:     w('<H1>Source tree</H1>')
   742: 
   743:     for level, type, name in data:
   744:       w(' '*(level*3)+' '+type+': '+name+ '<BR>')
   745: 
   746:     w('<H1>External Sources</H1>')
   747:     w('<H2>FTP Sources</H2>')
   748:     data = self.master.ftp_list
   749:     if not data:
   750:       data = self.pass_frame.ftp_list
   751: 
   752:     w('<TABLE COLS="4">')
   753:     w('<TR><TH>host</TH><TH>directory</TH><TH>filename</TH><TH>local</TH></TR>')
   754:     for remote_host,remote_directory,remote_filename, local_filename in data:
   755:       w('<TR><TD>'+remote_host+\
   756:         '</TD><TD>'+remote_directory+\
   757:         '</TD><TD>'+remote_filename+\
   758:         '</TD><TD>'+local_filename+'</TD></TR>')
   759:     w('</TABLE>')
   760:     w('</BODY>')
   761:     w('</HTML>')
   762:     return 1
   763: 
   764:   def mk_metricsref(self,filename,target):
   765:     data = self.master.iflist
   766:     if not data:
   767:       data = self.pass_frame.iflist
   768:     if len(data) ==0: return 0
   769:     sink = named_file_sink(
   770:       self.pass_frame,
   771:       self.basedir+filename,
   772:       self.master.weaver_prefix,
   773:       eol=self.eol)
   774:     w = sink.writeline
   775:     self.mk_head(sink)
   776:     w ('<BODY LANG="'+self.language+'">')
   777: 
   778:     w('<H1>Software Metrics</H1>')
   779: 
   780:     for name, count in data:
   781:       w(name+ ': '+str(count)+' LOC<BR>')
   782: 
   783:     w('</BODY>')
   784:     w('</HTML>')
   785:     return 1
   786: 
   787:   def mk_noticesref(self,filename,target):
   788:     data = self.master.noticedict
   789:     if len(data)==0: return 0
   790:     sink = named_file_sink(
   791:       self.pass_frame,
   792:       self.basedir+filename,
   793:       self.master.weaver_prefix,
   794:       eol=self.eol)
   795:     w = sink.writeline
   796:     self.mk_head(sink)
   797:     w ('<BODY LANG="'+self.language+'">')
   798: 
   799:     w('<H1>Notices</H1>')
   800:     keys = data.keys()
   801:     keys.sort()
   802:     for key in keys:
   803:       value = data[key]
   804:       w('<A HREF="'+key+'.html" TARGET="notices">'+key+'</A>')
   805:       sink2 = named_file_sink(
   806:         self.pass_frame,
   807:         self.basedir+key+'.html',
   808:         self.master.weaver_prefix,
   809:         eol=self.eol)
   810:       w2 = sink2.writeline
   811:       self.mk_head(sink)
   812:       w2( '<BODY>')
   813:       w2('<PRE>')
   814:       sink2.write(cvt_text(value))
   815:       w2('</PRE>')
   816:       w2('</BODY>')
   817:       w2('</HTML>')
   818:       del w2
   819:       del sink2
   820:     w('</BODY>')
   821:     w('</HTML>')
   822:     return 1
   823: 
   824:   def mk_testref(self,filename,target):
   825:     ids = self.master.tests
   826:     if len(ids) == 0:
   827:       ids = self.pass_frame.tests
   828:     if len(ids)==0: return 0
   829:     sink = named_file_sink(
   830:       self.pass_frame,
   831:       self.basedir+filename,
   832:       self.master.weaver_prefix,
   833:       eol=self.eol)
   834:     w = sink.writeline
   835:     self.mk_head(sink)
   836:     w ('<BODY LANG="'+self.language+'">')
   837: 
   838:     w('<H1>Index of Tests</H1>')
   839:     w('<TABLE CLASS="TEST_SUMMARY_TABLE" COLS="4" BORDER="1">')
   840:     w('<TR><TH>No</TH><TH>Description</TH><TH>Kind</TH><TH>Result</TH><TR>')
   841:     keys = ids.keys()
   842:     keys.sort()
   843:     for key in keys:
   844:       descr, label, kind, result = ids[key]
   845:       href = self.get_anchor(label)
   846:       w('<TR><TD>'+str(key)+'</TD><TD><A TARGET="'+target+'" HREF="'+href+'">'+descr+'</A></TD><TD>'+kind+'</TD><TD>'+result+'</TD></TR>')
   847:     w('</TABLE>')
   848:     w('</BODY>')
   849:     w('</HTML>')
   850:     return 1
   851: 
   852:   def mk_filestatus(self,filename,target):
   853:     if 'weavers' in self.process.trace:
   854:       print 'Creating file status file:',filename
   855:     filestatus_output = simple_named_file_sink(
   856:       self.pass_frame,self.basedir+filename, self.master.weaver_prefix,eol='\r\n')
   857:     filestatus_weaver = html_weaver(
   858:       self.pass_frame,
   859:       filestatus_output,title='File Status', language=self.language)
   860:     filestatus_weaver.print_file_status(hlevel=1)
   861:     return 1
   862: 
   863:   def set_fc_anchor(self,file,count):
   864:     filename = self.base[0].sink.basename
   865:     self.anchor_file[(file,count)]=filename
   866:     for weaver in self.base:
   867:       weaver.set_fc_anchor(file,count)
   868: 
   869:   def heading_reference(self, *args, **kwds): pass # always generated
   870:   def identifier_reference(self, *args, **kwds): pass # always generated
   871:   def class_reference(self, *args, **kwds): pass # always generated
   872:   def function_reference(self, *args, **kwds): pass # always generated
   873:   def test_reference(self, *args, **kwds): pass # always generated
   874: 
   875: 
End python section to interscript/weavers/web.py[8]