# - - - T m p l P o o l . _ _ i n i t _ _ - - -
(by inspection: the invariant on self.__templateMap is satisfied
for an empty dictionary)
# - - - T m p l P o o l . _ _ g e t i t e m _ _ - - -
#### Case 1: self contains a Template for file eff-name(name)
self.__templateMap: @
#-- 1 --
if key is None: fileName = DEFAULT_TEMPLATE
else: fileName = key
self.__templateMap: @
fileName: eff-name(key)
#-- 2 --
# [ if self.templateMap has a key (fileName) ->
# return the corresponding value
# else -> I ]
return @(self.__templateMap)[fileName], which is the template
for fileName by the class invariant
#-- TARGET -- OK
[ if (name is a string or None) ->
if self contains a Template for file eff-name(name) ->
return that Template
else if eff_name(name) names a readable, valid template
file ->
self := self + a Template object representing that file
return that Template object
else ->
raise IOError ]
# - - - T m p l P o o l . _ _ g e t i t e m _ _ - - -
#### Case 2: eff-name(key) names a readable, valid template file
file.__templateMap: @
#-- 1 --
if key is None: fileName = DEFAULT_TEMPLATE
else: fileName = key
self.__templateMap: @
fileName: eff-name(key), by definition of eff-name
#-- 2 --
# [ if self.templateMap has a key (fileName) -> ...
# else -> I ]
self.__templateMap: @
fileName: eff-name(key), by definition of eff-name
#-- 3 --
# [ if fileName names a readable, valid template file ->
# result := a Template object representing that file
# else -> ... ]
self.__templateMap: @
fileName: eff-name(key), by definition of eff-name
result: a Template object representing eff-name(key)
#-- 4 --
self.__templateMap[fileName] = result
self.__templateMap: @+(entry mapping eff-name(key) |-> a Template
object representing eff-name(key))
fileName: eff-name(key), by definition of eff-name
result: a Template object representing eff-name(key)
#-- 5 --
return result
self.__templateMap: @+(entry mapping eff-name(key) |-> a Template
object representing eff-name(key))
fileName: eff-name(key), by definition of eff-name
result: a Template object representing eff-name(key)
return a Template object representing eff-name(key)
#-- TARGET -- OK
[ if (name is a string or None) ->
if self contains a Template for file eff-name(name) -> ...
else if eff_name(name) names a readable, valid template
file ->
self := self + a Template object representing that file
return that Template object
else -> ... ]
# - - - T m p l P o o l . _ _ g e t i t e m _ _ - - -
#### Case 3: eff-name(key) is not in self, and key
#### doesn't name a readable, valid template file
self.__templateMap: @
#-- 1 --
if key is None: fileName = DEFAULT_TEMPLATE
else: fileName = key
self.__templateMap: @
fileName: eff-name(key)
#-- 2 --
# [ if self.templateMap has a key (fileName) -> ...
# else -> I ]
self.__templateMap: @
fileName: eff-name(key)
#-- 3 --
# [ if fileName names a readable, valid template file ->
# else -> raise IOError ]
raise IOError
#-- TARGET -- OK
[ if (name is a string or None) ->
if self contains a Template for file eff-name(name) -> ...
else if eff_name(name) names a readable, valid template
file -> ...
else ->
raise IOError ]
# - - - T T o k e n . _ _ i n i t _ _ - - -
(virtual constructor; must be replaced by subclass)
# - - - T T o k e n . w r i t e L i n k - - -
by inspection: fromTopic is a Topic object by precondition;
toTarget is a Target object by precondition; and the I/F of
Topic.relPath(toTarget) is:
[ if toTarget is a Target object ->
return the pathname (and optional anchor) which, when used
in self's directory, points to the output file of toTarget ]
# - - - T T o k e n . w r i t e S t d L i n k - - -
(by inspection)
# - - - L i t e r a l T o k e n . _ _ i n i t _ _ - - -
TToken.__init__ ( self, openCondStack, scan )
self.text: Undefined
self.text = text
self.text: text
#-- TARGET -- OK
Generic:
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is a conditional expansion token -> ...
else if ifStack is skipping -> I
else ->
outFile +:= the expansion of self in the context of body ]
Specific:
.text: [ as passed to the constructor ]
# - - - L i t e r a l T o k e n . e x p a n d - - -
#### Case 1: ifStack.isSkipping() is true
if not ifStack.isSkipping():
outFile.write ( self.text )
(no change)
#-- TARGET -- OK
Generic:
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is a conditional expansion token -> ...
else if ifStack is skipping -> I
else -> ... ]
# - - - L i t e r a l T o k e n . e x p a n d - - -
#### Case 2: ifStack.isSkipping() is false
outFile: @
if not ifStack.isSkipping():
outFile.write ( self.text )
outFile: @+self.text
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is a conditional expansion token -> ...
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - A u t h o r T o k e n . e x p a n d - - -
#### Case 1: ifStack.isSkipping() is true
if ( ( not ifStack.isSkipping() ) and
( body.author ) ):
outFile.write ( body.author )
(no changes)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is a conditional expansion token -> ...
else if ifStack is skipping -> I
else -> ... ]
# - - - A u t h o r T o k e n . e x p a n d - - -
#### Case 2: ifStack.isSkipping() is true; body.author is false
if ( ( not ifStack.isSkipping() ) and
( body.author ) ):
outFile.write ( body.author )
(no changes)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is a conditional expansion token -> ...
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - A u t h o r T o k e n . e x p a n d - - -
#### Case 3: ifStack.isSkipping() is true; body.author is true
if ( ( not ifStack.isSkipping() ) and
( body.author ) ):
outFile.write ( body.author )
outFile: @+body.author
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack ->
raise SyntaxError
else if self is a valid conditional expansion token -> ...
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - B o d y T o k e n . e x p a n d - - -
#### Case 1: ifStack.isSkipping() is true
if not ifStack.isSkipping():
body.expand ( outFile )
(no changes)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a conditional expansion token -> ...
else if ifStack is skipping -> I
else -> ... ]
# - - - B o d y T o k e n . e x p a n d - - -
#### Case 2: ifStack.isSkipping() is false
if not ifStack.isSkipping():
body.expand ( outFile )
outFile: @+(strings from list body.text)
Note: Invariant on body.text reads:
[ if self is valid ->
self's expanded body text as a list of strings
else -> None ]
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token ->
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - E l s e T o k e n . _ _ i n i t _ _ - - -
#### Case 1: There are no open conditions
#-- 1 --
# [ call parent constructor ]
(no change)
#-- 2 --
# [ if openCondStack is empty ->
# raise SyntaxError
# else -> I ]
raise SyntaxError
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack -> ...
else ->
raise SyntaxError ]
# - - - E l s e T o k e n . _ _ i n i t _ _ - - -
#### Case 2: The top condition on openCondStack has already seen
#### an `%else;'
#-- 1 --
# [ call parent constructor ]
(no changes)
#-- 2 --
# [ if openCondStack is empty -> ...
# else -> I ]
(no changes)
#-- 3 --
# [ if the top element of openCondStack has already
# seen an "%else;" ->
# raise SyntaxError
# else -> ... ]
raise SyntaxError
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack -> ...
else ->
raise SyntaxError ]
# - - - E l s e T o k e n . _ _ i n i t _ _ - - -
#### Case 3: The top condition on openCondStack has not seen
#### an `%else;'
#-- 1 --
# [ call parent constructor ]
(no changes)
#-- 2 --
# [ if openCondStack is empty -> ...
# else -> I ]
(no changes)
#-- 3 --
# [ if the top element of openCondStack has already
# seen an "%else;" -> ...
# else ->
# openCondStack := openCondStack with its top element's
# skipping state inverted and the
# passage of an "%else;" recorded ]
openCondStack: @ with its top element's skipping state inverted and
the passage of an `%else;' recorded
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack -> ...
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - E l s e T o k e n . e x p a n d - - -
#### Case 1: ifStack is empty
#-- 1 --
# [ if ifStack is empty ->
# raise SyntaxError
# else -> ... ]
raise SyntaxError
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack ->
raise SyntaxError
else if self is a valid conditional expansion token
in the context of ifStack ->
ifStack := ifStack adjusted to account for processing self
else if ifStack is skipping -> I
else ->
outFile +:= the expansion of self in the context of body ]
# - - - E l s e T o k e n . e x p a n d - - -
#### Case 2: ifStack has a top element and it has seen an `%else;'
#-- 1 --
# [ if ifStack is empty -> ...
# else if ifStack's top element has seen an else ->
# raise SyntaxError
# else -> ... ]
raise SyntaxError
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack ->
raise SyntaxError
else -> ... ]
# - - - E l s e T o k e n . e x p a n d - - -
#### Case 3: ifStack has a top element and it has not seen an `%else;'
#-- 1 --
# [ if ifStack is empty ->
# raise SyntaxError
# else if ifStack's top element has seen an else ->
# raise SyntaxError
# else ->
# ifStack := ifStack with the top Condition object's skipping
# state inverted and marked as having seen an `%else;' ]
ifStack: @ with its top Condition object's skipping state inverted and
marked as having seen an `%else;'
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack ->
ifStack := ifStack adjusted to account for processing self
else -> ... ]
# - - - E n d i f T o k e n . _ _ i n i t _ _ - - -
#### Case 1: openCondStack is empty
#-- 1 --
# [ call parent constructor ]
(no changes)
#-- 2 --
# [ if openCondStack is empty -> ...
# raise SyntaxError
# else -> ... ]
raise SyntaxError
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack -> ...
else ->
raise SyntaxError ]
# - - - E n d i f T o k e n . _ _ i n i t _ _ - - -
#### Case 2: openCondStack has at least one element
#-- 1 --
# [ call parent constructor ]
(no changes)
#-- 2 --
# [ if openCondStack is empty -> ...
# else ->
# openCondStack := openCondStack with its top element popped ]
openCondStack: @ with its top element popped
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - E n d i f T o k e n . e x p a n d - - -
#### Case 1: ifStack is empty
ifStack.end()
raise SyntaxError
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack ->
raise SyntaxError
else -> ... ]
# - - - E n d i f T o k e n . e x p a n d - - -
#### Case 2: ifStack is not empty
ifStack.end()
ifStack: @ with its top condition popped
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack ->
ifStack := ifStack adjusted to account for processing self
else -> ... ]
# - - - I f N e x t T o k e n . _ _ i n i t _ _ - - -
#-- 1 --
# [ call parent constructor ]
(no changes)
#-- 2 --
# [ openCondStack := openCondStack with a new OpenCond pushed
# that records scan.lineNo ]
openCondStack: @ with a new OpenCond pushed that records scan.lineNo
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - I f N e x t T o k e n . _ _ i n i t _ _ - - -
#-- 1 --
# [ call parent constructor ]
(no changes)
#-- 2 --
# [ openCondStack := openCondStack with a new OpenCond pushed
# that records scan.lineNo ]
openCondStack: @ + (a new OpenCond pushed that records scan.lineNo)
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - I f N e x t T o k e n . e x p a n d - - -
#-- 1 --
# [ if body has an effective next topic ->
# skipping := 0
# else ->
# skipping := 1 ]
skipping: (if body has a next topic -> 0, else -> 1)
#-- 2 --
# [ ifStack := ifStack with a new Condition object pushed,
# whose skipping attribute is (skipping) ]
skipping: 0
ifStack: @+(a new Condition object with skipping=(if body has a next
topic -> 0, else -> 1))
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack ->
ifStack := ifStack adjusted to account for processing self
else -> ... ]
# - - - I f P r e v T o k e n . _ _ i n i t _ _ - - -
#-- 1 --
# [ call parent constructor ]
(no change)
#-- 2 --
# [ openCondStack := openCondStack with a new OpenCond pushed
# that records scan.lineNo ]
openCondStack: @+(a new OpenCond that records scan.lineNo)
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - I f P r e v T o k e n . e x p a n d - - -
#-- 1 --
# [ if body has an effective previous topic ->
# skipping := 0
# else ->
# skipping := 1 ]
skipping: (if body has a prev topic -> 0, else -> 1)
#-- 2 --
# [ ifStack := ifStack with a new Condition object pushed,
# whose skipping attribute is (skipping) ]
skipping: (if body has a prev topic -> 0, else -> 1)
ifStack: @+(a new Condition with skipping=(if body has a prev topic -> 0,
else -> 1)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack ->
ifStack := ifStack adjusted to account for processing self
else -> ... ]
# - - - I f S e e T o k e n . _ _ i n i t _ _ - - -
#-- 1 --
# [ call parent constructor ]
(no change)
#-- 2 --
# [ openCondStack := openCondStack with a new OpenCond pushed
# that records scan.lineNo ]
openCondStack: @+(a new OpenCond that records scan.lineNo)
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - I f S e e T o k e n . e x p a n d - - -
#-- 1 --
# [ if body has an effective see-also topic ->
# skipping := 0
# else ->
# skipping := 1 ]
skipping: (if body has a see-also -> 0, else -> 1)
#-- 2 --
# [ ifStack := ifStack with a new Condition object pushed,
# whose skipping attribute is (skipping) ]
skipping: (if body has a see-also -> 0, else -> 1)
ifStack: @+(a new Condition with skipping=(if body has a see-also -> 0,
else -> 1)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack ->
ifStack := ifStack adjusted to account for processing self
else -> ... ]
# - - - N e x t T i t l e T o k e n . _ _ i n i t _ _ - - -
(does nothing)
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - N e x t T i t l e T o k e n . e x p a n d - - -
#### Case 1: ifStack is skipping or body has no next topic
# [ if (ifStack is skipping) or (body has no next topic) -> I
# else ->
# outFile +:= title of body's effective next topic ]
(no change)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> I
else -> ... ]
# - - - N e x t T i t l e T o k e n . e x p a n d - - -
#### Case 2: ifStack is not skipping and body has a next topic
# [ if (ifStack is skipping) or (body has no next topic) -> I
# else ->
# outFile +:= title of body's effective next topic ]
outFile: @+(title of body's effective next topic)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - N e x t U R L T o k e n . _ _ i n i t _ _ - - -
(do nothing)
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - N e x t U R L T o k e n . e x p a n d - - -
#### Case 1: (ifStack is skipping) or (body has no next topic)
# [ if (ifStack is skipping) or (body has no next topic) -> I
# else ->
# outFile +:= an tag linking from body to body's
# next topic ]
(no change)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> I
else -> ... ]
# - - - N e x t U R L T o k e n . e x p a n d - - -
#### Case 2: (ifStack is not skipping) and (body has a next topic)
# [ if (ifStack is skipping) or (body has no next topic) -> I
# else ->
# outFile +:= an tag linking from body to body's
# next topic ]
outFile: @+(an tag linking from body to body's next topic)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - P r e v T i t l e T o k e n . _ _ i n i t _ _ - - -
(do nothing)
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - P r e v T i t l e T o k e n . e x p a n d - - -
#### Case 1: (ifStack is skipping) or (body has no previous topic)
# [ if (ifStack is skipping) or (body has no previous topic) -> I
# else -> ... ]
(no change)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> I
else -> ... ]
# - - - P r e v T i t l e T o k e n . e x p a n d - - -
#### Case 2: (ifStack is not skipping) and (body has a previous topic)
# [ if (ifStack is skipping) or (body has no previous topic) -> I
# else ->
# outFile +:= title of body's effective previous topic ]
outFile: @+(title of body's effective previous topic)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - P r e v U R L T o k e n . _ _ i n i t _ _ - - -
(no change)
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - P r e v U R L T o k e n . e x p a n d - - -
#### Case 1: (ifStack is skipping) or (body has no previous topic)
# [ if (ifStack is skipping) or (body has no previous topic) -> I
# else ->
# outFile +:= an tag linking from body to body's
# previous topic ]
(no change)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> I
else -> ... ]
# - - - P r e v U R L T o k e n . e x p a n d - - -
#### Case 2: (ifStack is not skipping) and (body has a previous topic)
# [ if (ifStack is skipping) or (body has no previous topic) -> I
# else ->
# outFile +:= an tag linking from body to body's
# previous topic ]
outFile: @+(an tag linking from body to body's previous topic)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - S e e T o k e n . _ _ i n i t _ _ - - -
(no changes)
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - S e e T o k e n . e x p a n d - - -
#### Case 1: ifStack is skipping
#-- 1 --
# [ if ifStack is skipping ->
# return
# else -> I ]
(no changes)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> I
else -> ... ]
# - - - S e e T o k e n . e x p a n d - - -
#### Case 2: ifStack is skipping
#-- 1 --
# [ if ifStack is skipping ->
# return
# else -> I ]
(no changes)
#-- 2 --
prefix = ""
prefix: ""
#-- 3 --
# [ outFile := outFile + prefix + (a list of ...
# constructs, one per element of body.seeList, where each
# tag links from body to that element, and each link
# text is the title of that element, and the list elements
# are separated by "; " ]
prefix: ""
outFile: @+(a list of ... constructs, one per element of
body.seeList, where each tag links from body to that element,
and each link text is the title of that element, and the list elements
are separated by "; "
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - T i t l e T o k e n . _ _ i n i t _ _ - - -
(no changes)
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - T i t l e T o k e n . e x p a n d - - -
#### Case 1: ifStack is skipping
# [ if ifStack is skipping -> I
# else ->
# outFile +:= body's title ]
(no changes)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> I
else -> ... ]
# - - - T i t l e T o k e n . e x p a n d - - -
#### Case 2: ifStack is not skipping
# [ if ifStack is skipping -> I
# else ->
# outFile +:= body's title ]
outFile: @+(body's title)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - U R L T o k e n . _ _ i n i t _ _ - - -
(no changes)
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - U R L T o k e n . e x p a n d - - -
#### Case 1: ifStack is skipping
# [ if ifStack is skipping -> I
# else ->
# outFile +:= body's URL ]
(no changes)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> I
else -> ... ]
# - - - U R L T o k e n . e x p a n d - - -
#### Case 2: ifStack is not skipping
# [ if ifStack is skipping -> I
# else ->
# outFile +:= body's URL ]
outFile: @+(body's URL)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - U p d a t e T o k e n . _ _ i n i t _ _ - - -
(no changes)
#-- TARGET -- OK
[ if (openCondStack is a stack of OpenCond objects
representing %if-constructs not yet matched by "%endif;")
and (scan is a Scan object) ->
if this token is valid in the context of openCondStack ->
openCondStack := openCondStack adjusted for the token,
with a new OpenCond pushed containing scan.lineNo
if the token is an %if-construct
else -> ... ]
# - - - U p d a t e T o k e n . e x p a n d - - -
#### Case 1: (ifStack is skipping) or (body has no update string)
# [ if (ifStack is skipping) or (body has no update string) -> I
# else ->
# outFile +:= body's update string ]
(no changes)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> I
else -> ... ]
# - - - U p d a t e T o k e n . e x p a n d - - -
#### Case 2: (ifStack is not skipping) and (body has an update string)
# [ if (ifStack is skipping) or (body has no update string) -> I
# else ->
# outFile +:= body's update string ]
outFile: @+(body's update string)
#-- TARGET -- OK
[ if (ifStack is an IfStack object representing the current
nesting of %if-constructs)
and (body is a Body object representing the context in which
the token is to be expanded)
and (outFile is a writeable file handle) ->
if self is an invalid conditional expansion token in
the context of ifStack -> ...
else if self is a valid conditional expansion token
in the context of ifStack -> ...
else if ifStack is skipping -> ...
else ->
outFile +:= the expansion of self in the context of body ]
# - - - T e m p l a t e . _ _ i n i t _ _ - - -
#### Case 1: fileName names a readable, valid template file
#-- 1 --
self.fileName = fileName
self.__tokenList = []
self.__openCondStack = []
self.__ifStack = IfStack()
errCount = Log().count()
self.fileName: fileName
self.__tokenList: []
self.__openCondStack: []
self.__ifStack: an empty IfStack
errCount: @(Log().count())
#-- 2 --
# [ if self.fileName names a readable, valid template file ->
# self.__tokenList +:= a sequence of TToken objects
# representing the contents of that file
# self.__openCondStack := self.__openCondStack adjusted
# according to conditionals in that file
# else -> ... ]
self.fileName: fileName
self.__openCondStack: []
NB: If the template is valid, its conditionals must be balanced,
hence the net growth in __openCondStack is zero.
self.__ifStack: an empty IfStack
errCount: @(Log().count())
self.__tokenList: (sequence of TTokens representing fileName)
#-- 3 --
if errCount < Log().count():
raise IOError, "The template file was not error-free."
self.fileName: fileName
self.__openCondStack: []
self.__ifStack: an empty IfStack
errCount: @(Log().count())
self.__tokenList: (sequence of TTokens representing fileName)
#-- TARGET -- OK
[ if fileName is a string ->
if fileName names a readable, valid template file ->
return a new Template object representing that file
else -> ... ]
# - - - T e m p l a t e . _ _ i n i t _ _ - - -
#### Case 2: fileName doesn't name a readable, valid template file
#-- 1 --
self.fileName = fileName
self.__tokenList = []
self.__openCondStack = []
self.__ifStack = IfStack()
errCount = Log().count()
self.fileName: fileName
self.__tokenList: []
self.__openCondStack: []
self.__ifStack: an empty IfStack
errCount: @(Log().count())
#-- 2 --
# [ if self.fileName names a readable, valid template file -> ...
# else ->
# self.__tokenList +:= valid TTokens, if any
# self.__openCondStack := self.__openCondStack adjusted
# according to valid conditionals in that file
# Log() +:= error message(s) ]
self.fileName: fileName
self.__tokenList: list of valid TTokens, if any
self.__openCondStack: [Conditions for unmatched conditionals]
self.__ifStack: an empty IfStack
errCount: @(Log().count())+(number of errors, at least 1)
#-- 3 --
if errCount < Log().count():
raise IOError, "The template file was not error-free."
raise IOError
#-- TARGET -- OK
[ if fileName is a string ->
if fileName names a readable, valid template file -> ...
else ->
Log() +:= error message(s)
raise IOError ]
# - - - T e m p l a t e . _ _ r e a d F i l e - - -
#### Case 1: self.fileName does not name a readable file
#-- 1 --
# [ if self.fileName names a readable file -> ...
# else ->
# Log() +:= error message
# return ]
Log(): @+(error message)
return
#-- TARGET -- OK
[ if self.fileName names a readable, valid template file -> ...
else ->
self.__tokenList +:= valid TTokens, if any
self.__openCondStack := self.__openCondStack adjusted
according to valid conditionals in that file
Log() +:= error message(s) ]
# - - - T e m p l a t e . _ _ r e a d F i l e - - -
#### Case 2: self.fileName names a readable, template file that is
#### valid except for unclosed conditionals
#-- 1 --
# [ if self.fileName names a readable file ->
# scan := a new Scan object pointing to the start of that file
# else -> ... ]
scan: a Scan object pointing to the start of self.fileName
#-- 2 --
# [ if scan contains a valid template file -> ...
# scan := scan advanced to end of file
# self.__tokenList +:= a sequence of TToken objects
# representing the contents of scan
# self.__openCondStack := self.__openCondStack adjusted
# according to conditionals in scan
# else -> ... ]
scan: advanced to end of file
self.__tokenList: @+(valid TTokens from scan, if any
self.__openCondStack: @+(Conditions for unclosed conditionals in scan)
#-- 3 --
# [ if self.__openCondStack is empty -> ...
# else ->
# Log() +:= error message(s) ]
scan: advanced to end of file
self.__tokenList: @+(valid TTokens from scan, if any
self.__openCondStack: @+(Conditions for unclosed conditionals in scan)
Log(): @+(error message(s))
#-- TARGET -- OK
[ if self.fileName names a readable, valid template file -> ...
else ->
self.__tokenList +:= valid TTokens, if any
self.__openCondStack := self.__openCondStack adjusted
according to valid conditionals in that file
Log() +:= error message(s) ]
# - - - T e m p l a t e . _ _ r e a d F i l e - - -
#### Case 3: self.fileName names a readable template file that is invalid
#-- 1 --
# [ if self.fileName names a readable file ->
# scan := a new Scan object pointing to the start of that file
# else -> ... ]
scan: a Scan object pointing to the start of self.fileName
#-- 2 --
# [ if scan contains a valid template file -> ...
# else -> ...
# scan := scan advanced to end of file
# self.__tokenList +:= valid TTokens from scan, if any
# self.__openCondStack := self.__openCondStack adjusted
# according to valid conditionals in scan
# Log() +:= error message(s) ]
scan: @ advanced to EOF
self.__tokenList: @+(valid TTokens from scan, if any)
self.__openCondStack: @+(Conditions for open conditionals, if any)
Log(): @+(error message(s))
#-- 3 --
# [ if self.__openCondStack is empty -> I
# else -> ... ]
scan: @ advanced to EOF
self.__tokenList: @+(valid TTokens from scan, if any)
self.__openCondStack: @+(Conditions for open conditionals, if any)
Log(): @+(error message(s))
#-- TARGET -- OK
[ if self.fileName names a readable, valid template file -> ...
else ->
self.__tokenList +:= valid TTokens, if any
self.__openCondStack := self.__openCondStack adjusted
according to valid conditionals in that file
Log() +:= error message(s) ]
# - - - T e m p l a t e . _ _ r e a d F i l e - - -
#### While: termination
#### Case 1: File is empty -> scan.endFile will be set initially
#### Case 2: scan starts with a valid format code -> scan is advanced
#### Case 3: scan starts with a bad format code ->
scan is advanced at least one
#### Case 4: scan does not start with a format code -> scan is advanced
to the next format code or EOF
#### While: False case -> assume scan.atEndFile is true -> OK
self.__tokenList: no change
self.__openCondStack: no change
#### While: True case
#### Case 1: scan starts with a valid format code
# [ if scan starts with a valid format code ->
# scan := scan advanced past that format code
# self.__tokenList +:= a TToken object representing
# that code
# else -> ... ]
scan: scan advanced past that format code
self.__tokenList: @+(a TToken object representing that code)
# [ if scan contains a valid template file ->
# scan := scan advanced to end of file
# self.__tokenList +:= a sequence of TToken objects
# representing the contents of scan
# self.__openCondStack := self.__openCondStack adjusted
# according to conditionals in scan
# else ->
# scan := scan advanced to end of file
# self.__tokenList +:= valid TTokens from scan, if any
# self.__openCondStack := self.__openCondStack adjusted
# according to valid conditionals in scan
# Log() +:= error message(s) ]
scan: scan advanced to end of file
self.__tokenList: @+(a TToken object representing that code)+(sequence
of TToken objects representing the contents of scan)
self.__openCondStack: @ adjusted for that code if necessary, then
adjusted for contents of scan
#-- TARGET -- OK
# [ if scan contains a valid template file ->
# scan := scan advanced to end of file
# self.__tokenList +:= a sequence of TToken objects
# representing the contents of scan
# self.__openCondStack := self.__openCondStack adjusted
# according to conditionals in scan
# else ->
# scan := scan advanced to end of file
# self.__tokenList +:= valid TTokens from scan, if any
# self.__openCondStack := self.__openCondStack adjusted
# according to valid conditionals in scan
# Log() +:= error message(s) ]
#### Case 2: scan starts with a bad format code
# [ if scan starts with a valid format code -> ...
# else if scan starts with a bad format code ->
# scan := scan advanced the valid part, at least one
# Log() +:= error message
# else -> ... ]
scan: @ advanced past valid part, at least one
Log(): @+(error message)
# [ if scan contains a valid template file ->
# scan := scan advanced to end of file
# self.__tokenList +:= a sequence of TToken objects
# representing the contents of scan
# self.__openCondStack := self.__openCondStack adjusted
# according to conditionals in scan
# else ->
# scan := scan advanced to end of file
# self.__tokenList +:= valid TTokens from scan, if any
# self.__openCondStack := self.__openCondStack adjusted
# according to valid conditionals in scan
# Log() +:= error message(s) ]
scan: @ advanced to EOF
Log(): @+(error message)+(errors from scan, if any)
self.__tokenList: @+(TTokens from scan)
self.__openCondStack: @, adjusted from scan
#-- TARGET -- OK
# [ if scan contains a valid template file ->
# scan := scan advanced to end of file
# self.__tokenList +:= a sequence of TToken objects
# representing the contents of scan
# self.__openCondStack := self.__openCondStack adjusted
# according to conditionals in scan
# else ->
# scan := scan advanced to end of file
# self.__tokenList +:= valid TTokens from scan, if any
# self.__openCondStack := self.__openCondStack adjusted
# according to valid conditionals in scan
# Log() +:= error message(s) ]
#### Case 3: scan does not start with a format code
# [ if scan starts with a valid format code -> ...
# else if scan starts with a bad format code -> ...
# else ->
# scan := scan advanced up to the next format code or EOF
# self.__tokenList +:= a TToken representing all text
# up to the next format code or EOF ]
scan: @ advanced to next format code or EOF
self.__tokenList: @+(literal token for text up to next format code or EOF)
# [ if scan contains a valid template file ->
# scan := scan advanced to end of file
# self.__tokenList +:= a sequence of TToken objects
# representing the contents of scan
# self.__openCondStack := self.__openCondStack adjusted
# according to conditionals in scan
# else ->
# scan := scan advanced to end of file
# self.__tokenList +:= valid TTokens from scan, if any
# self.__openCondStack := self.__openCondStack adjusted
# according to valid conditionals in scan
# Log() +:= error message(s) ]
scan: @ advanced to EOF
self.__tokenList: @+(literal token for text up to next format code or EOF)+
(tokens from scan)
self.__openCondStack: @ adjusted according to scan
Log(): @+(errors from scan, if any)
#-- TARGET -- OK
# [ if scan contains a valid template file ->
# scan := scan advanced to end of file
# self.__tokenList +:= a sequence of TToken objects
# representing the contents of scan
# self.__openCondStack := self.__openCondStack adjusted
# according to conditionals in scan
# else ->
# scan := scan advanced to end of file
# self.__tokenList +:= valid TTokens from scan, if any
# self.__openCondStack := self.__openCondStack adjusted
# according to valid conditionals in scan
# Log() +:= error message(s) ]
# - - - T e m p l a t e . _ _ r e a d T o k e n - - -
#### Case 1: scan starts with START_FORMAT not followed by a valid
#### format code
#-- 1 --
# [ if scan starts with a START_FORMAT not followed by a valid
# format code ->
# scan := scan advanced past the START_FORMAT and any
# following valid part
# Log() +:= error message
# else if scan starts with a valid format code -> ...
# else -> ... ]
scan: @ advanced past the START_FORMAT and any following valid part
Log(): @+(error message)
#-- TARGET -- OK
[ if scan starts with a valid format code -> ...
else if scan starts with a bad format code ->
scan := scan advanced the valid part, at least one
Log() +:= error message
else -> ... ]
# - - - T e m p l a t e . _ _ r e a d T o k e n - - -
#### Case 2: scan starts with a valid format code
#-- 1 --
# [ if scan starts with a START_FORMAT not followed by a valid
# format code -> ...
# else if scan starts with a valid format code ->
# scan := scan advanced past the format code
# self.__tokenList +:= a TToken representing the format code
# self.__openCondStack := self.__openCondStack adjusted
# for that code, if necessary
# else -> ... ]
scan: @ advanced past the leading format code
self.__tokenList: @+(a TToken representing that format code)
self.__openCondStack: @, adjusted for the format code if necessary
#-- TARGET -- OK
[ if scan starts with a valid format code ->
scan := scan advanced past that format code
self.__tokenList +:= a TToken object representing
that code
self.__openCondStack := self.__openCondStack adjusted
for that code, if necessary
else if scan starts with a bad format code -> ...
else -> ... ]
# - - - T e m p l a t e . _ _ r e a d T o k e n - - -
#### Case 3: scan does not start with a format code
#-- 1 --
# [ if scan starts with a START_FORMAT not followed by a valid
# format code -> ...
# else if scan starts with a valid format code -> ...
# else ->
# scan := scan advanced up to the next format code or EOF
# self.__tokenList +:= a TToken representing all text
# up to the next format code or EOF ]
scan: @, advanced up to the next format code or EOF
self.__tokenList: @+(a TToken repr. all text up to next format code or EOF)
#-- TARGET -- OK
[ if scan starts with a valid format code -> ...
else if scan starts with a bad format code -> ...
else ->
scan := scan advanced up to the next format code
self.__tokenList +:= a TToken representing all text
up to the next format code or EOF ]
# - - - T e m p l a t e . _ _ r e a d T o k e n - - -
#### 1 vs 1.1/1.2: Case 1, scan starts with a START_FORMAT
#### followed by a valid format code
if scan.tabMatch ( START_FORMAT ):
scan: @, advanced past START_FORMAT
#-- 1.1 --
# [ if scan starts with a valid format code name followed by
# END_FORMAT ->
# scan := scan advanced past all that
# self.__tokenList +:= a TToken representing that
# format code
# self.__openCondStack := self.__openCondStack adjusted
# for that code, if necessary
# else -> ... ]
scan: @, advanced past START_FORMAT, format code name, and END_FORMAT
self.__tokenList: @+(a TToken representing that format code)
self.__openCondStack: @, adjusted for that format code if necessary
#-- TARGET -- OK
#-- 1 --
# [ if scan starts with a START_FORMAT not followed by a valid
# format code -> ...
# else if scan starts with a valid format code ->
# scan := scan advanced past the format code
# self.__tokenList +:= a TToken representing the format code
# self.__openCondStack := self.__openCondStack adjusted
# for that code, if necessary
# else -> ... ]
# - - - T e m p l a t e . _ _ r e a d T o k e n - - -
#### 1 vs 1.1/1.2: Case 2, scan starts with a START_FORMAT *not*
#### followed by a valid format code
if scan.tabMatch ( START_FORMAT ):
scan: @, advanced past START_FORMAT
#-- 1.1 --
# [ if scan starts with a valid format code name followed by
# END_FORMAT -> ...
# else ->
# scan := scan advanced past any leading characters
# in FORMAT_NAME_CSET, then END_FORMAT if present
# Log() +:= error message ]
scan: @, advanced past START_FORMAT and any leading characters in
FORMAT_NAME_CSET and END_FORMAT if present
Log: @+(error message)
#-- TARGET -- OK
#-- 1 --
# [ if scan starts with a START_FORMAT not followed by a valid
# format code ->
# scan := scan advanced past the START_FORMAT and any
# following valid part
# Log() +:= error message
# else if scan starts with a valid format code -> ...
# else -> ... ]
# - - - T e m p l a t e . _ _ r e a d T o k e n - - -
#### 1 vs 1.1/1.2: Case 3, scan doesn't start with START_FORMAT
if scan.tabMatch ( START_FORMAT ):
scan: @
#-- 1.2 --
# [ scan := scan advanced up to the next
# START_FORMAT or EOF
# self.__tokenList +:= a literal TToken containing all
# characters from scan up to the
# next START_FORMAT or EOF ]
scan: @, advanced to the next START_FORMAT or EOF
self.__tokenList: @+(a literal TToken containing all characters from
scan up to the next START_FORMAT or EOF
#-- TARGET -- OK
#-- 1 --
# [ if scan starts with a START_FORMAT not followed by a valid
# format code -> ...
# else if scan starts with a valid format code -> ...
# else ->
# scan := scan advanced up to the next format code or EOF
# self.__tokenList +:= a TToken representing all text
# up to the next format code or EOF ]
# - - - T e m p l a t e . _ _ r e a d L i t e r a l - - -
#### Case 1: At least one START_FORMAT remains in scan
#-- 1 --
L = []
L: []
#-- 2 --
# [ if at least one START_FORMAT remains in scan ->
# scan := scan advanced up to the first START_FORMAT
# L +:= text up to the first START_FORMAT as a sequence
# of strings
# else -> ... ]
scan: @, advanced up to the first START_FORMAT
L: text up to the first START_FORMAT in scan, as a sequence of strings
#-- 3 --
# [ self.__tokenList := a LiteralToken representing the
# concatenation of the strings in L ]
scan: @, advanced up to the first START_FORMAT
L: text up to the first START_FORMAT in scan, as a sequence of strings
self.__tokenList: @+(a LiteralToken representing the text up to the first
START_FORMAT in scan)
#-- TARGET -- OK
[ scan := scan advanced up to the next
START_FORMAT or EOF
self.__tokenList +:= characters from scan up to the
next START_FORMAT or EOF ]
# - - - T e m p l a t e . _ _ r e a d L i t e r a l - - -
#### Case 2: No START_FORMAT remains in scan
#-- 1 --
L = []
L: []
#-- 2 --
# [ if at least one START_FORMAT remains in scan -> ...
# else ->
# scan := scan advanced to EOF
# L +:= text remaining in scan as a sequence of strings ]
scan: @, advanced to EOF
L: text from @(scan) to EOF as a sequence of strings
#-- 3 --
# [ self.__tokenList := a LiteralToken representing the
# concatenation of the strings in L ]
scan: @, advanced to EOF
L: text from @(scan) to EOF as a sequence of strings
self.__tokenList: @+(a LiteralToken representing all text from @(scan)
to EOF)
#-- TARGET -- OK
[ scan := scan advanced up to the next
START_FORMAT or EOF
self.__tokenList +:= characters from scan up to the
next START_FORMAT or EOF ]
# - - - T e m p l a t e . _ _ r e a d L i t e r a l - - -
#### While, case 1: line in scan contains a START_FORMAT
done = 0
done: 0
#-- 2 body --
# [ if line in scan contains a START_FORMAT ->
# scan := scan advanced up to the first START_FORMAT
# L +:= text from scan up to the first START_FORMAT
# done := 1
# else if line in scan is the last in the file -> ...
# else -> ... ]
done: 1
scan: @, advanced up to the first START_FORMAT
L: @+(text from scan up to the first START_FORMAT)
#-- TARGET -- OK
# [ if at least one START_FORMAT remains in scan ->
# scan := scan advanced up to the first START_FORMAT
# L +:= text up to the first START_FORMAT in scan,
# as a sequence of strings
# else -> ... ]
# - - - T e m p l a t e . _ _ r e a d L i t e r a l - - -
#### While, case 2: line in scan does not contain a START_FORMAT
#### and line in scan is last in file
done = 0
done: 0
#-- 2 body --
# [ if line in scan contains a START_FORMAT -> ...
# else if line in scan is the last in the file ->
# scan := scan advanced to EOF
# L +:= remaining text in scan
# done := 1
# else -> ... ]
done: 1
scan: @, advanced to EOF
L: @+(remaining text from scan)
#-- TARGET -- OK
# [ if at least one START_FORMAT remains in scan -> ...
# else ->
# scan := scan advanced to EOF
# L +:= text remaining in scan as a sequence of strings ]
# - - - T e m p l a t e . _ _ r e a d L i t e r a l - - -
#### While, case 3: line in scan does not contain a START_FORMAT,
#### line in scan is not last in file, and file contains no more START_FORMAT
done = 0
done: 0
#-- 2 body --
# [ if line in scan contains a START_FORMAT -> ...
# else if line in scan is the last in the file -> ...
# else ->
# scan := scan advanced to the next line
# L +:= (remaining text on line in scan) + "\n"
# done := 0 ]
done: 0
scan: @, advanced to next line
L: @+(remaining text from line in scan+"\n")
#-- 2 --
# [ if at least one START_FORMAT remains in scan -> ...
# else ->
# scan := scan advanced to EOF
# L +:= text remaining in scan as a sequence of strings
# done := 1 ]
done: 1
scan: @, advanced to EOF
L: @+(remaining text from line in scan+"\n"+text remaining in scan)
#-- TARGET -- OK
#-- 2 --
# [ if at least one START_FORMAT remains in scan -> ...
# else ->
# scan := scan advanced to EOF
# L +:= text remaining in scan as a sequence of strings ]
# done := 1 ]
# - - - T e m p l a t e . _ _ r e a d L i t e r a l - - -
#### While, case 4: line in scan does not contain a START_FORMAT,
#### line in scan is not last in file, and file contains another START_FORMAT
done = 0
done: 0
#-- 2 body --
# [ if line in scan contains a START_FORMAT -> ...
# else if line in scan is the last in the file -> ...
# else ->
# scan := scan advanced to the next line
# L +:= (remaining text on line in scan) + "\n"
# done := 0 ]
done: 0
scan: @, advanced to next line
L: @+(remaining text from line in scan+"\n")
#-- 2 --
# [ if at least one START_FORMAT remains in scan ->
# scan := scan advanced up to the first START_FORMAT
# L +:= text up to the first START_FORMAT in scan,
# as a sequence of strings
# done := 1
# else -> ... ]
done: 1
scan: @, advance to first START_FORMAT
L: @+(remaining text from line in scan+"\n"+text up to first START_FORMAT
in scan)
#-- TARGET -- OK
#-- 2 --
# [ if at least one START_FORMAT remains in scan ->
# scan := scan advanced up to the first START_FORMAT
# L +:= text up to the first START_FORMAT in scan,
# as a sequence of strings
# done := 1
# else ->
# scan := scan advanced to EOF
# L +:= text remaining in scan as a sequence of strings ]
# done := 1 ]
# - - - T e m p l a t e . _ _ r e a d L i t e r a l L i n e - - -
#### Case 1: line in scan contains a START_FORMAT
#-- 1 --
# [ if line in scan contains a START_FORMAT ->
# endp := position of the first such
# else -> ... ]
endp: position of the first START_FORMAT in scan's line
#-- 2 --
# [ if endp is None -> ...
# else ->
# scan := endp
# L +:= text from scan up to endp
# return 1 ]
scan: position of the first START_FORMAT past @
L: @+(text from @(scan) up to endp)
return 1
#-- TARGET -- OK
[ if (scan is a Scan object) and (L is a list) ->
if line in scan contains a START_FORMAT ->
scan := scan advanced up to the first START_FORMAT
L +:= text from scan up to the first START_FORMAT
return 1
else if line in scan is the last in the file -> ...
else -> ... ]
# - - - T e m p l a t e . _ _ r e a d L i t e r a l L i n e - - -
#### Case 2: line in scan contains no START_FORMAT and is last line
#-- 1 --
# [ if line in scan contains a START_FORMAT ->
# endp := position of the first such
# else ->
# endp := None ]
endp: None
#-- 2 --
# [ if endp is None ->
# scan := scan advanced to the next line
# L +:= (remainder of line in scan) + "\n"
# else -> ... ]
scan: @, advanced to EOF
L: @+(remainder of line in scan)
#-- 3 --
if scan.atEndFile:
return 1
else:
return 0
scan: @, advanced to EOF
L: @+(remainder of line in scan)
return 1
#-- TARGET -- OK
[ if (scan is a Scan object) and (L is a list) ->
if line in scan contains a START_FORMAT -> ...
else if line in scan is the last in the file ->
scan := scan advanced to EOF
L +:= remaining text in scan
return 1
else -> ... ]
# - - - T e m p l a t e . _ _ r e a d L i t e r a l L i n e - - -
#### Case 3: line in scan contains no START_FORMAT and is not last line
#-- 1 --
# [ if line in scan contains a START_FORMAT ->
# endp := position of the first such
# else ->
# endp := None ]
endp: None
#-- 2 --
# [ if endp is None ->
# scan := scan advanced to the next line
# L +:= (remainder of line in scan) + "\n"
# else -> ... ]
endp: None
scan: @, advanced to next line
L: @+(remainder of line in scan+"\n")
#-- 3 --
if scan.atEndFile:
return 1
else:
return 0
endp: None
scan: @, advanced to next line
L: @+(remainder of line in scan+"\n")
return 0
#-- TARGET -- OK
[ if (scan is a Scan object) and (L is a list) ->
if line in scan contains a START_FORMAT -> ...
else if line in scan is the last in the file -> ...
else ->
scan := scan advanced to the next line
L +:= (remaining text on line in scan) + "\n"
return 0 ]
# - - - T e m p l a t e . _ _ r e a d F o r m a t - - -
#### Case 1: scan starts with START_FORMAT (doubled %% case)
#-- 1 --
# [ if scan starts with START_FORMAT ->
# scan := scan advanced one
# self.__tokenList +:= a LiteralToken containing "%"
# return
# else -> I ]
if scan.tabMatch ( START_FORMAT ):
self.__tokenList.append ( LiteralToken ( START_FORMAT ) )
return
scan: @, advanced one
self.__tokenList: @+(a LiteralToken containing START_FORMAT)
return
#-- TARGET -- OK
[ if (scan is a Scan object) ->
if scan starts with START_FORMAT ->
scan := scan advanced one
self.__tokenList +:= a literal TToken containing
START_FORMAT
eles if scan starts with a valid format code name followed by
END_FORMAT -> ...
else -> ... ]
# - - - T e m p l a t e . _ _ r e a d F o r m a t - - -
#### Case 2: scan starts with a character not in FORMAT_NAME_CSET
#-- 1 --
# [ if scan starts with START_FORMAT -> ...
# else -> I ]
I
#-- 2 --
# [ if scan starts with a character in FORMAT_NAME_CSET -> ...
# else ->
# Log() +:= error message
# return ]
Log(): @+(error message)
return
#-- TARGET -- OK
[ if (scan is a Scan object) ->
if scan starts with START_FORMAT -> ...
else if scan starts with a valid format code name followed by
END_FORMAT -> ...
else ->
scan := scan advanced past any leading characters
in FORMAT_NAME_CSET, then END_FORMAT if present
Log() +:= error message ]
# - - - T e m p l a t e . _ _ r e a d F o r m a t - - -
#### Case 3: scan starts with one or more characters in FORMAT_NAME_CSET
#### but they are not followed by END_FORMAT
#-- 1 --
# [ if scan starts with START_FORMAT -> ...
# else -> I ]
I
#-- 2 --
# [ if scan starts with a character in FORMAT_NAME_CSET ->
# scan := scan advanced past all leading characters in
# FORMAT_NAME_CSET
# gi := those characters, lowercased (NB: `gi' stands
# for `generic identifier,' which is the standard term for
# the name of an SGML tag)
# else -> ... ]
scan: @, advanced past all leading characters in FORMAT_NAME_CSET
gi: all leading characters in FORMAT_NAME_CSET from scan
#-- 3 --
# [ if scan starts with END_FORMAT -> ...
# else ->
# Log() +:= error message
# return ]
scan: @, advanced past all leading characters in FORMAT_NAME_CSET
gi: all leading characters in FORMAT_NAME_CSET from scan
Log(): @+(error message)
return
#-- TARGET -- OK
[ if (scan is a Scan object) ->
if scan starts with START_FORMAT -> ...
else if scan starts with a valid format code name followed by
END_FORMAT -> ...
else ->
scan := scan advanced past any leading characters
in FORMAT_NAME_CSET, then END_FORMAT if present
Log() +:= error message ]
# - - - T e m p l a t e . _ _ r e a d F o r m a t - - -
#### Case 4: scan starts with a string that is a key NOT in `formatScanners'
#### followed by END_FORMAT
#-- 1 --
# [ if scan starts with START_FORMAT -> ...
# else -> I ]
I
#-- 2 --
# [ if scan starts with a character in FORMAT_NAME_CSET ->
# scan := scan advanced past all leading characters in
# FORMAT_NAME_CSET
# gi := those characters, lowercased (NB: `gi' stands
# for `generic identifier,' which is the standard term for
# the name of an SGML tag)
# else ->
# Log() +:= error message
# return ]
scan: scan advanced past all leading characters in FORMAT_NAME_CSET
gi: all leading characters from scan in FORMAT_NAME_CSET
#-- 3 --
# [ if scan starts with END_FORMAT ->
# scan := scan advanced one
# else ->
# Log() +:= error message
# return ]
scan: scan advanced past all leading characters in FORMAT_NAME_CSET
and then past END_FORMAT
gi: all leading characters from scan in FORMAT_NAME_CSET
#-- 4 --
# [ if gi is a key in self.formatScanners)
# and (the corresponding value can be used as a constructor
# in the context of self.__openCondStack and scan) -> ...
# else ->
# Log() +:= error message ]
scan: scan advanced past all leading characters in FORMAT_NAME_CSET
and then past END_FORMAT
gi: all leading characters from scan in FORMAT_NAME_CSET
Log(): @+(error message)
#-- TARGET -- OK
[ if (scan is a Scan object) ->
if scan starts with START_FORMAT -> ...
else if scan starts with a valid format code name followed by
END_FORMAT -> ...
else ->
scan := scan advanced past any leading characters
in FORMAT_NAME_CSET, then END_FORMAT if present
Log() +:= error message ]
# - - - T e m p l a t e . _ _ r e a d F o r m a t - - -
#### Case 5: scan starts with a string that IS a key in `formatScanners'
#### followed by END_FORMAT
#-- 1 --
# [ if scan starts with START_FORMAT ->
# scan := scan advanced one
# self.__tokenList +:= a LiteralToken containing START_FORMAT
# return
# else -> I ]
I
#-- 2 --
# [ if scan starts with a character in FORMAT_NAME_CSET ->
# scan := scan advanced past all leading characters in
# FORMAT_NAME_CSET
# gi := those characters, lowercased (NB: `gi' stands
# for `generic identifier,' which is the standard term for
# the name of an SGML tag)
# else ->
# Log() +:= error message
# return ]
scan: @, advanced past all leading characters in FORMAT_NAME_CSET
gi: all leading characters from scan in FORMAT_NAME_CSET, lowercased
#-- 3 --
# [ if scan starts with END_FORMAT ->
# scan := scan advanced one
# else ->
# Log() +:= error message
# return ]
scan: @, advanced past all leading characters in FORMAT_NAME_CSET
and then one more
gi: all leading characters from scan in FORMAT_NAME_CSET, lowercased
#-- 4 --
# [ if gi is a key in self.formatScanners)
# and (the corresponding value can be used as a constructor
# in the context of self.__openCondStack and scan) ->
# self.__tokenList +:= an object so constructed
# self.__openCondStack := self.__openCondStack adjusted
# by that constructor
# else ->
# Log() +:= error message ]
scan: @, advanced past all leading characters in FORMAT_NAME_CSET
and then one more
gi: all leading characters from scan in FORMAT_NAME_CSET, lowercased
self.__tokenList: @+(self.formatScanners[gi] used as a constructor
in the context of self.__openCondStack and scan)
self.__openCondStack: @, adjusted by (self.formatScanners[gi] used as a
constructor in the context of self.__openCondStack and scan)
#-- TARGET -- OK
[ if (scan is a Scan object) ->
if scan starts with START_FORMAT -> ...
else if scan starts with a valid format code name followed by
END_FORMAT ->
scan := scan advanced past all that
self.__tokenList +:= a TToken representing that
format code
self.__openCondStack := self.__openCondStack adjusted
for that format code
else -> ... ]
# - - - O p e n C o n d . _ _ i n i t _ _ - - -
(trivial)
# - - - O p e n C o n d . e l s e - - -
#### Case 1: self.hasElse is 0
if self.hasElse:
raise SyntaxError, ( "Only one `%else;' clause is allowed "
"to match the `%%%s;' on line %d." %
( self.name, self.lineNo ) )
else:
self.hasElse = 1
self.hasElse: 1
#-- TARGET -- OK
[ if self.hasElse ->
raise SyntaxError
else ->
self.hasElse := 1 ]
# - - - O p e n C o n d . e l s e - - -
#### Case 2: self.hasElse is 1
if self.hasElse:
raise SyntaxError, ( "Only one `%else;' clause is allowed "
"to match the `%%%s;' on line %d." %
( self.name, self.lineNo ) )
else:
self.hasElse = 1
raise SyntaxError
#-- TARGET -- OK
[ if self.hasElse ->
raise SyntaxError
else ->
self.hasElse := 1 ]
# - - - I f S t a c k . _ _ i n i t _ _ - - -
self.__stack: []
#-- TARGET -- OK
.__stack:
[ a list of Condition objects, used as a stack with the base
at element 0, representing the nested %if-condition constructs
at the current point of template expansion ]
# - - - I f S t a c k . s t a r t - - -
self.__stack.append ( cond )
self.__stack: @+(cond)
#-- TARGET -- OK
[ if (cond is a Condition object) ->
self := self with cond pushed on the stack ]
# - - - I f S t a c k . e n d - - -
#### Case 1: self.__stack is empty
if len ( self.__stack ) === 0:
raise SyntaxError, "Mismatched `%end;' conditional"
else: ...
raise SyntaxError
#-- TARGET -- OK
[ if self's stack contains at least one element -> ...
else -> raise SyntaxError ]
# - - - I f S t a c k . e n d - - -
#### Case 2: self.__stack is not empty
if len ( self.__stack ) == 0: ...
else:
result = self.__stack[-1]
del __stack[-1]
return result
self.__stack: @-(top)
result: top of @(self.__stack)
#-- TARGET -- OK
[ if self's stack contains at least one element ->
self := self with the top condition popped
return that condition
else -> ... ]
# - - - I f S t a c k . e l s e C h e c k - - -
#### Case 1: self.__stack is empty
if len ( self.__stack ) == 0:
#-- 1.1 --
raise SyntaxError, "Mismatched `%else;' conditional"
else: ...
raise SyntaxError
#-- TARGET -- OK
[ if self's stack is empty ->
raise SyntaxError
else if self's top element has seen an else -> ...
else -> ... ]
# - - - I f S t a c k . e l s e C h e c k - - -
#### Case 2: self.__stack's top element has not seen an `%else;'
if len ( self.__stack ) == 0: ...
else:
#-- 1.2 --
# [ if self.__stack has at least one element ->
# if top of self.__stack has seen an `%else;' -> ...
# else ->
# self.__stack := self.__stack with the sense of
# its top condition reversed ]
self.__stack: @ with sense of top condition reversed
#-- TARGET --
[ if self's stack is empty -> ...
else if self's top element has seen an else -> ...
else ->
self := self with the top Condition object's skipping
state inverted and marked as having seen an `%else;' ]
# - - - I f S t a c k . e l s e C h e c k - - -
#### Case 3: self.__stack's top element has seen an `%else;'
if len ( self.__stack ) == 0: ...
else:
#-- 1.2 --
# [ if self.__stack has at least one element ->
# if top of self.__stack has seen an `%else;' ->
# raise SyntaxError
# else -> ... ]
raise SyntaxError
#-- TARGET -- OK
[ if self's stack is empty -> ...
else if self's top element has seen an else ->
raise SyntaxError
else -> ... ]
# - - - I f S t a c k . i s S k i p p i n g - - -
#### Case 1: self.__stack is empty
#-- 1 --
# [ if self.__stack is empty ->
# return 0
# else -> I ]
return 0
#-- TARGET -- OK
[ if self's state implies that we are currently skipping tokens ->
return 1
else -> return 0 ]
# - - - I f S t a c k . i s S k i p p i n g - - -
#### Case 2: self.__stack is not empty and at least one condition
#### in self.__stack is skipping
#-- 1 --
# [ if self.__stack is empty ->
# return 0
# else -> I ]
I
#-- 2 --
# [ if any of the conditions in self.__stack is skipping ->
# return 1
# else -> I ]
return 1
#-- TARGET -- OK
[ if self's state implies that we are currently skipping tokens ->
return 1
else -> return 0 ]
# - - - I f S t a c k . i s S k i p p i n g - - -
#### Case 3: self.__stack is not empty and none of the conditions
#### in self.__stack are skipping
#-- 1 --
# [ if self.__stack is empty ->
# return 0
# else -> I ]
I
#-- 2 --
# [ if any of the conditions in self.__stack is skipping ->
# return 1
# else -> I ]
I
#-- 3 --
return 0
return 0
#-- TARGET -- OK
[ if self's state implies that we are currently skipping tokens ->
return 1
else -> return 0 ]
# - - - C o n d i t i o n . _ _ i n i t _ _ - - -
self.skipping: skipping
self.hasElse: 0
#-- TARGET -- OK
.skipping:
[ if self is skipping -> 1
else -> 0 ]
.hasElse:
[ if self has seen an `%else;' -> 1
else -> 0 ]
# - - - C o n d i t i o n . _ _ e l s e C h e c k - - -
#### Case 1: self.hasElse is 1
if self.hasElse:
raise SyntaxError, ( "Only one `%else;' can be used per "
"`%if...;' construct." )
else: ...
raise SyntaxError
#-- TARGET -- OK
[ if self has seen an `%else' ->
raise SyntaxError
else if self.skipping is 1 -> ...
else -> ... ]
# - - - C o n d i t i o n . _ _ e l s e C h e c k - - -
#### Case 2: self.hasElse is 0 and self.skipping is 0
self.hasElse: 0
self.skipping: 0
if self.hasElse: ...
else:
self.hasElse = 1
if self.skipping: self.skipping = 0
else: self.skipping = 1
self.hasElse: 1
self.skipping: 1
#-- TARGET -- OK
[ if self has seen an `%else' -> ...
else if self.skipping is 1 -> ...
else ->
self.skipping := 1
self.hasElse := 1 ]
# - - - C o n d i t i o n . _ _ e l s e C h e c k - - -
#### Case 3: self.hasElse is 0 and self.skipping is 1
self.hasElse: 0
self.skipping: 1
if self.hasElse: ...
else:
self.hasElse = 1
if self.skipping: self.skipping = 0
else: self.skipping = 1
self.hasElse: 1
self.skipping: 0
#-- TARGET -- OK
[ if self has seen an `%else' -> ...
else if self.skipping is 1 ->
self.skipping := 0
self.hasElse := 1
else -> ... ]