# 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