# - - - B o d y . _ _ i n i t _ _ - - - #### Case 1: fileName does not name a readable, valid body file #-- 1 -- self.topic = topic self.seeList = [] self.etemplate = topic.defaultTemplate self.topic: topic self.seeList: [] self.etemplate: topic.defaultTemplate #-- 2 -- # [ self.enext := a Target object representing self.topic's # right-hand sibling in topic.plan, if any, # else None # self.eprev := a Target object representing self.topic's # left-hand sibling in topic.plan, if any, # else None # self.seeList := self.seeList + (a Target object # representing self.topic's parent, if any) ] self.topic: topic self.seeList: [(a Target representing self.topic's parent, if any)] self.etemplate: topic.defaultTemplate self.enext: Target representing self.topic's RH sibling in topic.plan, if any, else None self.eprev: Target representing self.topic's LH sibling in topic.plan, if any, else None #-- 3 -- # [ if fileName names a readable, valid body file -> ... # else -> # Log() +:= error message(s) # self.topic.plan := self.topic.plan with link variants # added from that file, if any # raise IOError ] self.topic: topic self.seeList: [(a Target representing self.topic's parent, if any)] self.etemplate: topic.defaultTemplate self.enext: Target representing self.topic's RH sibling in topic.plan, if any, else None self.eprev: Target representing self.topic's LH sibling in topic.plan, if any, else None self.topic.plan: @ with link variants added from fileName, if any Log(): @+(error message) raise IOError #-- TARGET -- OK [ if (topic is a Topic object) and (fileName is a string) -> if fileName names a readable, valid body file -> ... else -> Log() +:= error message(s) raise IOError ] # - - - B o d y . _ _ i n i t _ _ - - - #### Case 2: fileName names a readable, valid body file #-- 1 -- self.topic = topic self.seeList = [] self.etemplate = topic.defaultTemplate self.topic: topic self.seeList: [] self.etemplate: topic.defaultTemplate #-- 2 -- # [ self.enext := a Target object representing self.topic's # right-hand sibling in topic.plan, if any, # else None # self.eprev := a Target object representing self.topic's # left-hand sibling in topic.plan, if any, # else None # self.seeList := self.seeList + (a Target object # representing self.topic's parent, if any) ] self.topic: topic self.seeList: [(a Target representing self.topic's parent, if any)] self.etemplate: topic.defaultTemplate self.enext: Target representing self.topic's RH sibling in topic.plan, if any, else None self.eprev: Target representing self.topic's LH sibling in topic.plan, if any, else None #-- 3 -- # [ if fileName names a readable, valid body file -> # self := self modified to reflect the contents # of that file # self.topic.plan := self.topic.plan with link variants # added from that file # else -> ... ] self.topic: topic self.seeList: [(a Target representing self.topic's parent, if any)] self.etemplate: topic.defaultTemplate self.enext: Target representing self.topic's RH sibling in topic.plan, if any, else None self.eprev: Target representing self.topic's LH sibling in topic.plan, if any, else None self: @, modified to reflect the contents of fileName self.topic.plan: @ with link variants added from fileName #-- TARGET -- OK [ if (topic is a Topic object) and (fileName is a string) -> if fileName names a readable, valid body file -> return a new Body object representing that fileName as that topic else -> ... ] (invariants) .topic: As passed to constructor .author: [ if self contains an tag -> the content of that tag as a string else -> None ] .seeList: [ effective-see-list(self, self.topic.plan) ] .enext: [ effective-next(self, self.topic.plan) ] .eprev: [ effective-prev(self, self.topic.plan) ] .etemplate: [ effective-template(self, self.topic.plan) ] .text: [ if self is valid -> self's expanded body text as a list of strings else -> None ] .updated: [ if self contains an tag -> the value of the DATE attribute as a string else -> None ] # - - - B o d y . _ _ f i n d S i b l i n g s - - - #### Case 1: self is the root #-- 1 -- self.enext = None self.eprev = None self.enext: None self.eprev: None #-- 2 -- # [ if self.topic has no parent -> # return # else -> ... ] self.enext: None self.eprev: None return #-- TARGET -- [ self.enext := a Target object representing self.topic's right-hand sibling in topic.plan, if any, else None self.eprev := a Target object representing self.topic's left-hand sibling in topic.plan, if any, else None self.seeList := self.seeList + (a Target object representing self.topic's parent, if any) ] # - - - B o d y . _ _ f i n d S i b l i n g s - - - #### Case 2: self is not the root #-- 1 -- self.enext = None self.eprev = None self.enext: None self.eprev: None #-- 2 -- # [ if self.topic has no parent -> ... # else -> # parent := parent of self.topic # self.seeList +:= a Target representing parent of self.topic ] self.enext: None self.eprev: None self.seeList: @+(a Target representing self.topic's parent) #-- 3 -- # [ if self.topic has no left sibling -> I # else -> # self.eprev := a Target object for self.topic's left sibling ] self.enext: None self.eprev: if self.topic has a left sibling, a Target object for that sibling, else None self.seeList: @+(a Target representing self.topic's parent) #-- 4 -- # [ if self.topic has no right sibling -> I # else -> # self.enext := a Target object for self.topic's right sibling ] self.enext: if self.topic has a right sibling, a Target object for that sibling, else None self.eprev: if self.topic has a left sibling, a Target object for that sibling, else None self.seeList: @+(a Target representing self.topic's parent) #-- TARGET -- OK [ self.enext := a Target object representing self.topic's right-hand sibling in topic.plan, if any, else None self.eprev := a Target object representing self.topic's left-hand sibling in topic.plan, if any, else None self.seeList := self.seeList + (a Target object representing self.topic's parent, if any) ] # - - - B o d y . _ _ r e a d - - - #### Case 1: fileName does not name a readable file #-- 1 -- # [ errCount := err count from Log() # self.text := "" ] errCount: @(Log().count()) self.text: "" #-- 2 -- # [ if fileName names a readable file -> ... # else -> # Log() +:= error message # raise IOError ] errCount: @(Log().count()) self.text: "" Log(): @+(error message) raise IOError #-- TARGET -- OK [ if fileName names a readable, valid body file -> ... else -> Log() +:= error message(s) self.topic.plan := self.topic.plan with link variants added from that file, if any raise IOError ] # - - - B o d y . _ _ r e a d - - - #### Case 2: fileName is readable but not valid #-- 1 -- # [ errCount := err count from Log() # self.text := "" ] errCount: @(Log().count()) self.text: "" #-- 2 -- # [ if fileName names a readable file -> # scan := a new Scan object positioned at the start of # that file # else -> ... ] errCount: @(Log().count()) self.text: "" scan: a Scan object positioned at the start of fileName #-- 3 -- # [ if scan contains a valid body file -> ... # else -> # Log() +:= error message(s) # self := self modified to reflect valid parts # of the file, if any # self.topic.plan := self.topic.plan with valid link variants # added from that file, if any ] errCount: @(Log().count()) self.text: "" scan: a Scan object positioned at the start of fileName Log(): @+(error message(s)) self: @, modified to reflect valid parts of fileName, if any self.topic.plan: @ with valid link variants added from fileName, if any #-- 4 -- # [ if errCount < (count of errors from Log()) -> # raise IOError # else -> ... ] errCount: @(Log().count()) self.text: "" scan: a Scan object positioned at the start of fileName Log(): @+(error message(s)) self: @, modified to reflect valid parts of fileName, if any self.topic.plan: @ with valid link variants added from fileName, if any raise IOError #-- TARGET -- OK [ if fileName names a readable, valid body file -> ... else -> Log() +:= error message(s) self.topic.plan := self.topic.plan with link variants added from that file, if any raise IOError ] # - - - B o d y . _ _ r e a d - - - #### Case 3: fileName is readable and valid #-- 1 -- # [ errCount := err count from Log() # self.text := "" ] errCount: @(Log().count()) self.text: "" #-- 2 -- # [ if fileName names a readable file -> # scan := a new Scan object positioned at the start of # that file # else -> ... ] errCount: @(Log().count()) self.text: "" scan: a Scan object positioned at the start of fileName #-- 3 -- # [ if scan contains a valid body file -> # self := self modified to reflect the contents of # that file # self.topic.plan := self.topic.plan with link variants added # from that file # else -> ... ] errCount: @(Log().count()) self.text: "" scan: a Scan object positioned at the start of fileName self: @, modified to reflect the contents of fileName self.topic.plan: @ with link variants added from fileName # - - - B o d y . _ _ r e a d T o k e n - - - #### Case 1: scan starts with a badly-formed tag #-- 1 -- # [ if scan starts with "<" but that begins no valid SGML tag -> # scan := scan advanced after the next ">" or to EOF, # whichever comes first # Log() +:= error message(s) # else if input is a "<" starting a syntactically valid tag -> ... # else -> ... ] scan: @, advanced past the "<" and after the next ">" or EOF, whichever comes first Log(): @+(error message(s)) #-- TARGET -- OK [ if scan starts with a badly formed tag -> scan := scan advanced past the tag or to EOF if it is unclosed, at least one character Log() +:= error message(s) else ... ] # - - - B o d y . _ _ r e a d T o k e n - - - #### Case 2: scan starts with a valid tag that is one of our ours #-- 1 -- # [ if scan starts with "<" but that begins no valid SGML tag -> ... # else if input is a "<" starting a syntactically valid tag # that is one of ours -> # scan := scan advanced past the tag, and past its closing # tag if paired # self := self modified to reflect that tag # self.topic.plan := self.topic.plan with link variants added # from the tag, if any # Log() +:= error messages from expansion, if any # else -> ... ] scan: @, advanced past the tag, and past its closing tag if paired self: @, modified to reflect the tag self.topic.plan: @ + (link variants from the tag, if any) Log(): @+(error messages from expansion, if any) #-- TARGET -- OK [ if scan starts with a badly formed tag -> ... else if scan starts with one of our tags -> scan := scan advanced past that tag, and past its closing tag if paired self := self modified to reflect that tag Log() +:= error messages from expansion, if any self.topic.plan := self.topic.plan with link variants added from scan, if any else ... ] # - - - B o d y . _ _ r e a d T o k e n - - - #### Case 3: scan starts with a valid tag that is NOT one of our ours #-- 1 -- # [ if scan starts with "<" but that begins no valid SGML tag -> ... # else if input is a "<" starting a syntactically valid tag # that is one of ours -> ... # else if input starts with a valid tag that is not ours -> # scan := scan advanced past the tag # self.text +:= the equivalent of that tag # else -> ... ] scan: @, advanced past the tag self.text: @+(the equivalent of that tag) #-- TARGET -- OK [ if scan starts with a badly formed tag -> ... else if scan starts with one of our tags -> ... else if scan starts with a valid tag -> scan := scan advanced past that tag self.text := self.text + (the equivalent of that tag) else -> ... ] # - - - B o d y . _ _ r e a d T o k e n - - - #### Case 4: scan does not start with a tag #-- 1 -- # [ if scan starts with "<" but that begins no valid SGML tag -> ... # else if input is a "<" starting a syntactically valid tag # that is one of ours -> ... # else if input starts with a valid tag that is not ours -> ... # else -> # scan := scan advanced to the next "<" or to EOF, whichever # comes first # self.text +:= characters from scan up to the next "<" or # EOF, whichever comes first ] scan: @, advanced to the next "<" or EOF self.text: @+(characters from scan up to next "<" or EOF) #-- TARGET -- OK [ if scan starts with a badly formed tag -> ... else if scan starts with one of our tags -> ... else if scan starts with a valid tag -> ... else -> scan := scan advanced up to the next tag, or EOF, whichever comes first self.text := self.text + (characters from scan up to the next tag, or EOF, whichever comes first) ] # - - - B o d y . _ _ r e a d N o n T a g - - - #### Case 1: There is a "<" on the line in scan #### Termination: returns out of loop #### False case: can't happen #### True case #-- 1 loop -- # [ if there is a "<" on this line -> # scan := scan advanced up to the "<" # self.text +:= text from scan up to the "<" # return # else ... ] scan: @, advanced up to the first "<" on the current line self.text: @+(text from scan up to first "<") #-- TARGET -- OK [ scan := scan advanced to the next "<" or to EOF, whichever comes first self.text +:= characters from scan up to the next "<" or EOF, whichever comes first ] # - - - B o d y . _ _ r e a d N o n T a g - - - #### Case 2: Scan contains no "<" and is last line #### Termination: advances to EOF, terminates loop #### False case: at EOF, terminates loop #### True case: #-- 1 loop -- # [ if there is a "<" on this line -> ... # else if this is the last line in scan -> # scan := scan advanced to EOF # self.text +:= remainder of line in scan + "\n" # else -> ... ] scan: @, advanced to EOF self.text: @+(remainder of line in scan)+"\n" #-- TARGET -- OK [ scan := scan advanced to the next "<" or to EOF, whichever comes first self.text +:= characters from scan up to the next "<" or EOF, whichever comes first ] # - - - B o d y . _ _ r e a d N o n T a g - - - #### Case 3: Scan contains no "<" and is not last line #-- 1 loop -- # [ if there is a "<" on this line -> ... # else if this is the last line in scan -> ... # else -> # scan := scan advanced to the next line # self.text +:= remainder of line in scan + "\n" ] scan: @, advanced to next line self.text: @+(text remaining from line in scan)+"\n" [ scan := scan advanced to the next "<" or to EOF, whichever comes first self.text +:= characters from scan up to the next "<" or EOF, whichever comes first ] scan: @, advanced to next line, then to next "<" or EOF self.text: @+(text remaining from line in scan)+"\n"+(text up to next "<" or EOF) #-- TARGET --