6.19.10.2.22. Managing the tangler stack

These commands also push, pop, and set the tangler stack, but they also generate start and end section messages in the documentation file. They are intended for use by the end user.

Pushing and popping the stack is useful, for example, to temporarily write a C function declaration to the header file just before it is defined. (In fact, Interscript has some special case functionality to support this while avoiding writing the function signature twice.)

The begin and end comments functions push and pop the tangler stack, the push comments function pushes the comment tangler associated withe the current tangler (if there is a current tangler, otherwise it pushes None. The comment tangler associated with the current tangler could also be, and is by default, None.)

Note that the begin and end comments functions invoke the internal push and pop functions; that is, they do not write begin and end section messages to the documentation file. That's because the comments are actually written to the code file, they're just formatted by the weaver like documentation rather than code.

Design note: There is always a current tangler object, possibly None. Interscript knows it is writing code, except when the current tangler is None, in which case it is writing documentation. I'm not so sure this is a wonderful scheme :-(

The begin and end string functions write the enclosed lines to the code file formatted as a (single) string. The resultant output is echoed to the documentation file.

The begin and end string functions reformat the enclosed lines as a single string in the target programming language. In C, for example, special character such as slosh are replaced by two sloshes. (Note that a leading @ can be included only by writing @@).

The begin string function supports two optional arguments. The eol argument determines what to insert at the end of a line, it will usually be either an empty string, a newline character sequence, or a single space.

Trailing whitespace is removed from each line. It is not possible to disable this feature, and that is deliberate. However, a second argument, width, if positive, will then pad the line to the specified width with spaces. This feature is designed to support two dimensional character arrays.

Design note: there is as yet not support for international character sets.

Start python section to interscript/frames/inputf.py[32 /42 ] Next Prev First Last
   948: #line 1294 "input_frame.ipk"
   949:   def push(self,f):
   950:     "Push tangler onto tangler stack"
   951:     if self.current_tangler: self.code_foot()
   952:     self.tangler_push(f)
   953:     if self.current_tangler: self.code_head()
   954: 
   955:   def pop(self):
   956:     "Pop tangler from tangler stack"
   957:     if self.current_tangler: self.code_foot()
   958:     self.tangler_pop()
   959:     if self.current_tangler: self.code_head()
   960: 
   961: #line 1307 "input_frame.ipk"
   962:   def select(self, *args, **kwds):
   963:     "Select the nominated object as the current tangler or weaver"
   964:     for arg in args:
   965:       self.select1(arg)
   966:     if kwds.has_key('tangler'):
   967:       self.select_tangler(kwds['tangler'])
   968:     if kwds.has_key('weaver'):
   969:       self.set_weaver(kwds['weaver'])
   970: 
   971:   def select1(self, arg):
   972:     if has_protocol(arg,'tangler'):
   973:       self.select_tangler(arg)
   974:     elif has_protocol(arg, 'weaver'):
   975:       self.set_weaver(arg)
   976:     elif arg is None:
   977:       self.select_tangler(None)
   978:     else:
   979:       pass #permissive
   980: 
   981:   def select_tangler(self,f):
   982:     if self.current_tangler: self.code_foot()
   983:     self.tangler_set(f)
   984:     if self.current_tangler: self.code_head()
   985: 
   986:   def code_head(self):
   987:     dst_filename = self.current_tangler.sink.name
   988:     dst_lineno = self.current_tangler.sink.lines_written
   989:     src_filename = self.original_filename
   990:     src_lineno = self.original_count
   991: 
   992:     index = self.pass_frame.section_index
   993:     list = index.get(dst_filename, [])
   994:     list.append((dst_lineno, src_filename, src_lineno))
   995:     index[dst_filename]=list
   996:     secno = len(list)
   997:     self.current_weaver.code_head(self.current_tangler, secno)
   998: 
   999:   def code_foot(self):
  1000:     dst_filename = self.current_tangler.sink.name
  1001:     index = self.pass_frame.section_index
  1002:     list = index.get(dst_filename, [])
  1003:     secno = len(list)
  1004:     self.current_weaver.code_foot(self.current_tangler, secno)
  1005: 
  1006:   def begin_comments(self):
  1007:     "Begin tangling lines as comments"
  1008:     if self.current_tangler:
  1009:       self.current_tangler_push(self.current_tangler.get_comment_tangler())
  1010:     else:
  1011:       self.current_tangler_push(None)
  1012: 
  1013:   def end_comments(self):
  1014:     "End comment tangler"
  1015:     self.current_tangler_pop()
  1016: 
  1017:   def resume_code(self):
  1018:     "Pop the current tangler, use after starting string or comment tangler"
  1019:     self.current_tangler_pop()
  1020: 
  1021:   def comment(self,v):
  1022:     "Begin tangling an embedded comment."
  1023:     self.get_weaver().write_comment(v)
  1024: 
  1025:   def begin_string(self,eol = ' ', width = 0):
  1026:     "Begin tangling an embedded string."
  1027:     if self.current_tangler:
  1028:       self.current_tangler_push(self.current_tangler.get_string_tangler(eol,width))
  1029:     else:
  1030:       self.current_tangler_push(None)
  1031: 
  1032:   def end_string(self):
  1033:     "Terminate a string tangler"
  1034:     tangler_pop()
  1035: 
  1036:   def weave(self,s):
  1037:     "Weave a string of text"
  1038:     weaver = self.get_weaver()
  1039:     weaver.write(s)
  1040: 
  1041:   def weave_line(self,s):
  1042:     "Weave a line of text"
  1043:     weaver = self.get_weaver()
  1044:     weaver.writeline(s)
  1045: 
  1046:   def _tangle_line(self,s, inhibit_sref=0):
  1047:     "Tangle one line of code"
  1048:     if self.current_tangler:
  1049:       line = self.original_count
  1050:       file = self.original_filename
  1051:       self.current_tangler.writeline(s,file,line,inhibit_sref)
  1052:     else:
  1053:       print "tangle: No tangler for",s
  1054: 
  1055:   def tangle(self,s, inhibit_sref=0):
  1056:     "Tangle lines of code"
  1057:     lines = string.split(s,'\n')
  1058:     for line in lines:
  1059:       self._tangle_line(line,inhibit_sref)
  1060: 
  1061:   def sink_line(self,s):
  1062:     if self.current_tangler:
  1063:       snk = self.current_tangler.sink
  1064:       snk.writeline(s)
  1065:     else:
  1066:       print "tangle: No tangler for",s
  1067: 
End python section to interscript/frames/inputf.py[32]