# ttoken.icn: Template token objects for template.icn #-- $ifndef __TTOKEN_ICN__ $define __TTOKEN_ICN__ $define T_TOKEN_REVISION "$Revision: 1.13 $" $define T_TOKEN_DATE "$Date: 1996/02/18 19:59:07 $" #================================================================ # Class TToken: Each instance represents one atomic piece of a # template. #---------------------------------------------------------------- # tToken := T_Token_New ( expander, var ) # [ returns a new tToken with fields: # .expander := expander, a function which, when called as: # expander ( var, ifStack, body, outFile ) # will append to outFile the expansion of # tToken in the context of body and ifStack # .var := an object that will be passed to the expander #-- # T_Token_Expand ( tToken, ifStack, body, outFile ) # [ if the tToken is a conditional expansion token -> # ifStack := ifStack adjusted to reflect tToken # | else if ifStack is skipping -> I # | else -> # outFile ||:= expansion of tToken in the context of body # ] #---------------------------------------------------------------- # EXPANDERS. Each has the calling sequence: # expander ( var, ifStack, body, outFile ) # where the `var' is an object whose type and content depend on # the template type. # NOTE. Arguments shown below as `x' are unused. #---------------------------------------------------------------- # T_Token_Literal ( text, ifStack, body, outFile ) # [ if ifStack is skipping -> I # | else -> # outFile ||:= text # ] #-- # T_Token_Author ( x, ifStack, body, outFile ) # [ if ifStack is skipping -> I # | else -> # outFile ||:= author string from body, if any # ] #-- # T_Token_Body ( x, ifStack, body, outFile ) # [ if ifStack is skipping -> I # | else -> # outFile ||:= expansion of body # ] #-- # T_Token_Next_Title ( x, ifStack, body, outFile ) # [ if ifStack is skipping or body has no effective next topic -> I # | else -> # outFile ||:= title of that topic # ] #-- # T_Token_Next_URL ( x, ifStack, body, outFile ) # [ if ifStack is skipping or body has no effective next topic -> I # | else -> # outFile ||:= A tag where x is the relative # pathname from the body's topic to the # effective next topic # ] #-- # T_Token_Prev_Title ( x, ifStack, body, outFile ) # [ if ifStack is skipping or body has no effective previous topic -> I # | else -> # outFile ||:= title of that topic # ] #-- # T_Token_Prev_URL ( x, ifStack, body, outFile ) # [ if ifStack is skipping or body has no effective previous topic -> I # | else -> # outFile ||:= A tag where x is the relative # pathname from the body's topic to the # effective previous topic # ] #-- # T_Token_See ( x, ifStack, body, outFile ) # [ if ifStack is skipping -> I # | else -> # outFile ||:= semicolon-delimited list of links to topics in the # body's effective see-list, if any, such that each # link has the target topic's title as its link text # ] #-- # T_Token_Title ( x, ifStack, body, outFile ) # [ if ifStack is skipping -> I # | else -> # outFile ||:= title of body's topic # ] #-- # T_Token_URL ( x, ifStack, body, outFile ) # [ if ifStack is skipping -> I # | else -> # outFile ||:= (base URL from body's topic's plan's pathMap) || # (path from body's topic) || ".html" # ] #-- # T_Token_Updated ( x, ifStack, body, outFile ) # [ if ifStack is skipping or body has no tag -> I # | else -> # outFile ||:= body's revision string # ] #-- # T_Token_If_Next ( x, ifStack, body, outfile ) # [ if body has no effective next topic -> # ifStack := ifStack with a new condition pushed on it with: # .skipping := 1 # | else -> # ifStack := ifStack with a new condition pushed on it with: # .skipping := &null # ] #-- # T_Token_If_Prev ( x, ifStack, body, outfile ) # [ if body has no effective previous topic -> # ifStack := ifStack with a new condition pushed on it with: # .skipping := 1 # | else -> # ifStack := ifStack with a new condition pushed on it with: # .skipping := &null # ] #-- # T_Token_If_See ( x, ifStack, body, outfile ) # [ if body has no effective see topics -> # ifStack := ifStack with a new condition pushed on it with: # .skipping := 1 # | else -> # ifStack := ifStack with a new condition pushed on it with: # .skipping := &null # ] #-- # T_Token_Else ( x, ifStack, body, outFile ) # [ if ifStack is empty -> fail # | else -> # ifStack := ifStack with its top condition's .skipping # switch inverted # returns ifStack so modified # ] #-- # T_Token_Endif ( x, ifStack, body, outFile ) # [ if ifStack is empty -> fail # | else -> # ifStack := ifStack minus its top condition # return ifStack's (old) top condition # ] #---------------------------------------------------------------- record tTokenTag ( expander, # Expander function for this token var ) # Variant object to be passed to the expander # - - - T _ T o k e n _ N e w - - - procedure T_Token_New ( expander, var ) local tToken tToken := tTokenTag ( ); tToken.expander := expander; tToken.var := var; return tToken; end # --- T_Token_New --- # - - - T _ T o k e n _ E x p a n d - - - procedure T_Token_Expand ( tToken, ifStack, body, outFile ) tToken.expander ( tToken.var, ifStack, body, outFile ); end # - - - T _ T o k e n _ L i t e r a l - - - procedure T_Token_Literal ( text, ifStack, body, outFile ) if not If_Stack_Is_Skipping ( ifStack ) then writes ( outFile, text ); end # - - - T _ T o k e n _ A u t h o r - - - procedure T_Token_Author ( x, ifStack, body, outFile ) if not If_Stack_Is_Skipping ( ifStack ) then writes ( outFile, Body_Author ( body ) ); end # - - - T _ T o k e n _ B o d y - - - procedure T_Token_Body ( x, ifStack, body, outFile ) if not If_Stack_Is_Skipping ( ifStack ) then Body_Expand ( body, outFile ); end # - - - T _ T o k e n _ E l s e - - - procedure T_Token_Else ( x, ifStack, body, outFile ) return If_Stack_Else ( ifStack ); end # - - - T _ T o k e n _ E n d i f - - - procedure T_Token_Endif ( x, ifStack, body, outFile ) return If_Stack_End ( ifStack ); end # - - - T _ T o k e n _ I f _ N e x t - - - procedure T_Token_If_Next ( x, ifStack, body, outfile ) local target # Effective next-topic target local skipping # True if we are skipping tokens #-- 1 -- #-[ target := effective next topic of body #-] target := Body_Next ( body ); #-- 2 -- #-[ if target is &null -> # skipping := 1 # | else -> # skipping := &null #-] skipping := ( if ( / target ) then 1 else &null ); #-- 3 -- #-[ ifStack := ifStack with a new condition pushed whose .skipping # field is set from `skipping' #-] If_Stack_Start ( ifStack, Condition_New ( skipping ) ); end # --- T_Token_If_Next --- # - - - T _ T o k e n _ I f _ P r e v - - - procedure T_Token_If_Prev ( x, ifStack, body, outfile ) local target # Effective prev-topic target local skipping # True if we are skipping tokens #-- 1 -- #-[ target := effective previous topic of body #-] target := Body_Prev ( body ); #-- 2 -- #-[ if target is &null -> # skipping := 1 # | else -> # skipping := &null #-] skipping := ( if ( / target ) then 1 else &null ); #-- 3 -- #-[ ifStack := ifStack with a new condition pushed whose .skipping # field is set from `skipping' #-] If_Stack_Start ( ifStack, Condition_New ( skipping ) ); end # --- T_Token_If_Prev --- # - - - T _ T o k e n _ I f _ S e e - - - procedure T_Token_If_See ( x, ifStack, body, outfile ) local skipping # True if we are skipping tokens #-- 1 -- #-[ if body's effective see list has 1 or more entries -> # skipping := &null # | else -> # skipping := 1 #-] if Body_N_Sees ( body ) > 0 then skipping := &null else skipping := 1; #-- 2 -- #-[ ifStack := ifStack with a new condition pushed whose .skipping # field is set from `skipping' #-] If_Stack_Start ( ifStack, Condition_New ( skipping ) ); end # --- T_Token_If_See --- # - - - T _ T o k e n _ N e x t _ T i t l e - - - procedure T_Token_Next_Title ( x, ifStack, body, outFile ) local target #-- 1 -- #-[ if ifStack is skipping -> # return # | else -> I #-] if If_Stack_Is_Skipping ( ifStack ) then return; #-- 2 -- #-[ target := effective next topic of body #-] target := Body_Next ( body ); #-- 3 -- #-[ if target is &null -> I # | else -> # outFile ||:= title from target topic #-] writes ( outFile, Topic_Title ( Target_Topic ( \ target ) ) ); end # --- T_Token_Next_Title --- # - - - T _ T o k e n _ N e x t _ U R L - - - procedure T_Token_Next_URL ( x, ifStack, body, outFile ) local target #-- 1 -- #-[ if ifStack is skipping -> # return # | else -> I #-] if If_Stack_Is_Skipping ( ifStack ) then return; #-- 2 -- #-[ target := effective next topic of body #-] target := Body_Next ( body ); #-- 3 -- #-[ if target is &null -> I # | else -> # outFile ||:= an tag that links to the target topic #-] T_Token_Write_Link ( outFile, Body_Topic ( body ), \ target ); end # --- T_Token_Next_URL --- # - - - T _ T o k e n _ P r e v _ T i t l e - - - procedure T_Token_Prev_Title ( x, ifStack, body, outFile ) local target #-- 1 -- #-[ if ifStack is skipping -> # return # | else -> I #-] if If_Stack_Is_Skipping ( ifStack ) then return; #-- 2 -- #-[ target := effective previous topic of body #-] target := Body_Prev ( body ); #-- 3 -- #-[ if target is &null -> I # | else -> # outFile ||:= title from target topic #-] writes ( outFile, Topic_Title ( Target_Topic ( \ target ) ) ); end # --- T_Token_Prev_Title --- # - - - T _ T o k e n _ P r e v _ U R L - - - procedure T_Token_Prev_URL ( x, ifStack, body, outFile ) local target #-- 1 -- #-[ if ifStack is skipping -> # return # | else -> I #-] if If_Stack_Is_Skipping ( ifStack ) then return; #-- 2 -- #-[ target := effective previous topic of body #-] target := Body_Prev ( body ); #-- 3 -- #-[ if target is &null -> I # | else -> # outFile ||:= an tag that links to the target topic #-] T_Token_Write_Link ( outFile, Body_Topic ( body ), \ target ); end # --- T_Token_Prev_URL --- # - - - T _ T o k e n _ S e e - - - procedure T_Token_See ( x, ifStack, body, outFile ) local targetList #-- 1 -- #-[ if ifStack is skipping -> # return # | else -> I #-] if If_Stack_Is_Skipping ( ifStack ) then return; #-- 2 -- #-[ targetList := an empty list #-] targetList := []; #-- 3 -- #-[ if this body has any tags -> # targetList ||:= targets from body's tags # | else -> I #-] every put ( targetList, Body_Gen_Sees ( body ) ); #-- 4 -- #-[ outFile ||:= semicolon-delimited list of links from body.topic to # targets in targetList, with each having its title # as the link text #-] T_Token_Semi_Topic_List ( outFile, body.topic, targetList ); end # --- T_Token_See_Also --- # - - - T _ T o k e n _ S e m i _ T o p i c _ L i s t - - - #-[ outFile ||:= semicolon-delimited list of links from `topic' to each # target in list L, with each having its title as the # link text #-] procedure T_Token_Semi_Topic_List ( outFile, topic, L ) #-- 1 -- #-[ prefix := "" #-] local target local prefix prefix := ""; #-- 2 -- #-[ outfile ||:= prefix || semicolon-separated list of links # from `topic' to each topics in list L, with # each having its title as the link text # prefix := "; " #-] every target := ! L do { #-- 2.1 -- #-[ outFile ||:= prefix # prefix := "; " #-] writes ( outFile, prefix ); prefix := "; "; #-- 2.2 -- #-[ outfile ||:= an tag from `topic' to target, using the # title of `target' as the link text #-] T_Token_Write_Standard_Link ( outFile, topic, target ); } #-- 2.1 -- end # --- T_Token_Semi_Topic_List --- # - - - T _ T o k e n _ T i t l e - - - procedure T_Token_Title ( x, ifStack, body, outFile ) if not If_Stack_Is_Skipping ( ifStack ) then writes ( outFile, Topic_Title ( body.topic ) ); end # - - - T _ T o k e n _ U R L - - - procedure T_Token_URL ( x, ifStack, body, outFile ) if not If_Stack_Is_Skipping ( ifStack ) then writes ( outFile, Path_Map_Root_URL ( Plan_Path_Map ( Topic_Plan ( body.topic ) ) ), Topic_Path ( body.topic ), ".html" ); end # - - - T _ T o k e n _ U p d a t e d - - - procedure T_Token_Updated ( x, ifStack, body, outFile ) if not If_Stack_Is_Skipping ( ifStack ) then writes ( outFile, Body_Updated ( body ) ); end #================================================================ # PRIVATE METHODS #================================================================ # - - - T _ T o k e n _ W r i t e _ L i n k - - - #-[ outFile ||:= an tag that points from fromTopic to toTarget #-] procedure T_Token_Write_Link ( outFile, fromTopic, toTarget ) writes ( outFile, "" ); end # - - - T _ T o k e n _ W r i t e _ S t a n d a r d _ L i n k - - - #-[ outFile ||:= an tag that points from fromTopic to toTarget || # title of toTopic || "" #-] procedure T_Token_Write_Standard_Link ( outFile, fromTopic, toTarget ) T_Token_Write_Link ( outFile, fromTopic, toTarget ); writes ( outFile, Topic_Title ( Target_Topic ( toTarget ) ), "" ); end $endif