; NOTE to future maintainers: ; Make sure sub_sup_idl stays before translate_sub_super. At least ; for now, when IDL encounters a function and automatically compiles ; it, it only compiles the functions in the file up to the named ; function. So even if sub_sup_idl was declared with ; FORWARD_FUNCTION in translate_sub_super, it would not properly ; compile. ; ;+ ; SPECIAL NOTE: ; The file translate_sub_super.pro contains two functions, ; translate_sub_super, and sub_sup_idl. The former is the ; generic routine for processing TeX sub/superscripts, the ; latter is used only by translate_sub_super and has no general ; utility. Hence it lives here. You will see documentation for ; translate_sub_super second if you use DOC_LIBRARY. ;- ; ; ;+ ; NAME: ; SUB_SUP_IDL ; PURPOSE: ; Return the proper IDL font positioning command for TeX ; sub/superscripts. ; CATEGORY: ; TeXtoIDL ; CALLING SEQUENCE: ; fnt = sub_sup_idl( strn ) ; INPUTS: ; strn -- Either '^' or '_', the TeX super/subscript in ; characters ; KEYWORD PARAMETERS: ; /FORCE_UD -- Set this to use !U/!D instead of !E/!I for ; sub/superscripts . ; /HELP -- Set to print useful message and exit. ; OUTPUTS: ; fnt -- Either '!U' or !E' for superscripts, out ; or '!D' or '!I' for subscripts. ; COMMON BLOCKS: ; SIDE EFFECTS: ; NOTES: ; Used only by translate_sub_super. Should be kept in same ; file. ; EXAMPLE: ; MODIFICATION HISTORY: ; $Id: translate_sub_super.pro,v 1.5 2000/06/14 19:09:22 mcraig Exp $ ; $Log: translate_sub_super.pro,v $ ; Revision 1.5 2000/06/14 19:09:22 mcraig ; Changed name of strtok str_token to avoid conflict in IDL 5.3. ; ; Revision 1.4 1996/06/14 20:00:27 mcraig ; Updated Copyright info. ; ; Revision 1.3 1996/05/09 00:22:17 mcraig ; Changed some function calls to reflect changes in those functions, moved ; some code out of the main loop that didn't need to be there, added ; documentation. ; ; Revision 1.1 1996/01/31 18:47:37 mcraig ; Initial revision ; ; RELEASE: ; $Name: Rel_2_1 $ ; COPYRIGHT: ; Copyright (C) 1996 The Regents of the University of California, All ; Rights Reserved. Written by Matthew W. Craig. ; See the file COPYRIGHT for restrictions on distrubting this code. ; This code comes with absolutely NO warranty; see DISCLAIMER for details. ;- FUNCTION Sub_sup_idl, token, FORCE_UD = force_ud ; provide help if needed. IF (n_params() NE 1) OR keyword_set(Help) THEN BEGIN offset = ' ' print, offset+'Return the proper IDL font positioning command for TeX' print, offset+'sub/superscripts. ' print, offset+'fnt = sub_sup_idl( strn )' print, offset+'Inputs:' print, offset+offset+"strn -- Either '^' or '_', the TeX super/subscript in" print, offset+offset+' characters' print, offset+'Keywords:' print, offset+offset+'/FORCE_UD -- Set this to use !U/!D instead of !E/!I for' print, offset+offset+' sub/superscripts .' print, offset+offset+'/HELP -- Set to print useful message and exit.' print, offset+'Outputs:' print, offset+offset+"fnt -- Either '!U' or !E' for superscripts, out" print, offset+offset+" or '!D' or '!I' for subscripts." return, -1 ENDIF IF keyword_set(force_ud) THEN BEGIN IF (token EQ '^') THEN return, '!U' IF (token EQ '_') THEN return, '!D' return, '' ENDIF ELSE BEGIN IF (token EQ '^') THEN return, '!E' IF (token EQ '_') THEN return, '!I' return, '' ENDELSE END ; ;+ ; NAME: ; TRANSLATE_SUB_SUPER ; PURPOSE: ; Translate TeX sub/superscripts to IDL sub/superscripts. ; CATEGORY: ; text/strings ; CALLING SEQUENCE: ; new = translate_sub_super( old ) ; INPUTS: ; old -- string to be translated from TeX to IDL. in ; KEYWORD PARAMETERS: ; /RECURSED -- set if this function is being called ; recursively. ; /HELP -- Set to print useful message and exit. ; OUTPUTS: ; new -- string old converted from TeX to IDL out ; COMMON BLOCKS: ; SIDE EFFECTS: ; NOTES: ; - For best results, when both a sub and superscript are used, ; place the shorter of the two first (e.g. 'N^{a}_{bbbb}' is ; better than 'N_{bbbb}^{a}'). ; - Single character sub/super scripts do not need to be ; protected by braces. ; - Sub/superscripts may be nested (e.g. 'N^{N_1^N}'). ; EXAMPLE: ; out = translate_sub_super( 'N^2_{big}' ) ; Then out='N!U2!N!Dbig!N' which looks like it should on the ; display. ; LIBRARY FUNCTIONS CALLED: ; str_token -- Text/string (mcraig) ; sub_sup_idl -- contained in this file ; MODIFICATION HISTORY: ; $Id: translate_sub_super.pro,v 1.5 2000/06/14 19:09:22 mcraig Exp $ ; $Log: translate_sub_super.pro,v $ ; Revision 1.5 2000/06/14 19:09:22 mcraig ; Changed name of strtok str_token to avoid conflict in IDL 5.3. ; ; Revision 1.4 1996/06/14 20:00:27 mcraig ; Updated Copyright info. ; ; Revision 1.3 1996/05/09 00:22:17 mcraig ; Changed some function calls to reflect changes in those functions, moved ; some code out of the main loop that didn't need to be there, added ; documentation. ; ; Revision 1.2 1996/02/08 18:54:20 mcraig ; Changed default sub/superscript size to be !D/!U rather than !I/!E to ; improve readability of plat annotations. ; ; Revision 1.1 1996/01/31 18:47:37 mcraig ; Initial revision ; ; RELEASE: ; $Name: Rel_2_1 $ ; ; COPYRIGHT: ; Copyright (C) 1996 The Regents of the University of California, All ; Rights Reserved. Written by Matthew W. Craig. ; See the file COPYRIGHT for restrictions on distrubting this code. ; This code comes with absolutely NO warranty; see DISCLAIMER for details. ;- FUNCTION Translate_sub_super, InputString, $ RECURSED=recursed, $ HELP=Help ; Return to caller if error. On_error, 2 ; Offer help if needed and/or desired IF (n_params() NE 1) OR keyword_set(help) THEN BEGIN offset = ' ' print, offset+'Translate TeX sub/superscripts to IDL sub/superscripts.' print, offset+'new = translate_sub_super( old )' print, offset+'Inputs:' print, offset+offset+'old -- string to be translated from TeX to IDL. in' print, offset+'Keywords:' print, offset+offset+'/RECURSED -- set if this function is being called ' print, offset+offset+' recursively. ' print, offset+offset+'/HELP -- Set to print useful message and exit.' print, offset+'Outputs:' print, offset+offset+'new -- string old converted from TeX to IDL out' print, offset+'Notes:' print, offset+offset+'- For best results, when both a sub and superscript are used,' print, offset+offset+" place the shorter of the two first (e.g. 'N^{a}_{bbbb}' is" print, offset+offset+" better than 'N_{bbbb}^{a}')." print, offset+offset+'- Single character sub/super scripts do not need to be' print, offset+offset+' protected by braces.' print, offset+offset+"- Sub/superscripts may be nested (e.g. 'N^{N_1^N}')." return, -1 ENDIF ; To allow for nested scripts, use !E/!I instead of !U/!D for scripts ; when called recursively. IF (NOT keyword_set(recursed)) THEN $ ud = 1 $ ELSE $ ud = 0 ; Return to the normal level after making sub/superscript unless we ; are recursed, which indicates we are processing a nested script. IF keyword_set(recursed) THEN fontRestore = '' ELSE fontRestore = '!N' ; Initialize vars for processing scripts. SpcByte = (byte(' '))(0) ;We need the BYTE value for a space below. strn = InputString pos = 0 StorePos = '' RecallPos = '' OldToken = '' LenLastScript = 0 ; Grab next sub/superscript. Token will be either '^' or '_'. ; RETURN if no scripts. Token = nexttok(strn, '^_', pos = pos) if pos EQ -1 then return, InputString ;nothing to process. FntChange = sub_sup_idl(Token) ; Our approach will be to grab the input string up to the next '^' or ; '_', then process the script we've found. NewString=str_token(strn,Token) WHILE strlen(strn) GT 0 DO BEGIN ; Grab first char of sub/superscript. Script = strmid(strn, 0, 1) EndOfScript = 0 ;Position of end of this script. IF (Script EQ '{') THEN BEGIN ; Scripts of more than 1 char. EndOfScript = matchdelim(strn) Script = translate_sub_super(strmid(strn, 1, EndOfScript-1), $ /recursed ) ENDIF ; Grab rest of string _after_ the end of the script. strn = strmid(strn, EndOfScript+1, $ strlen(strn)-EndOfScript-1) ; Find the next script and prepare for processing it. FntChange = sub_sup_idl(Token, FORCE_UD = ud) OldToken = Token Token = nexttok(strn, '^_', POS = pos) ; If the input is 'n^2_j', we want the '2' to be directly above ; the 'j', rather than having the 'j' below and to the right of ; the 2. In other words, we want the first below, not the second. ; 2 2 ; N N ; J J ; To accomplish this, we need to save the position at which we ; begin writing the 2 with a !S, and restore that position with a ; !R after writing the 2. The first section in the IF block below ; handles the 'J' above, the thing after the first script. We ; don't care if there is another script following. We also padd ; the second script with spaces if it is shorter than the first to ; make sure that whatever comes out after the scripts starts in ; the proper place. The worry is that without the spaces, the ; input 'N^{looong}_{s} + 1' will end up with the + starting right ; the 's' ends. IF (StorePos EQ '!S') THEN BEGIN StorePos = '' RecallPos = '' ; calculate the difference in length between this script and the ; previous stacked one, removing font change commands (crudely by ; guessing that the number of characters this takes is twice the ; number of exclamation points). The + 1 below is a kludge. I ; don't know why, but I need one extra space. NumSpaces = LenLastScript - (strlen(script) - 2*strcnt(Script,'!')) NumSpaces = (NumSpaces + 1) > 0 IF NumSpaces GT 0 THEN $ Script = Script + string( replicate(SpcByte, NumSpaces) ) ENDIF ELSE BEGIN IF (Token NE OldToken) AND (pos EQ 0) THEN BEGIN ; The next script immediately folows this one. Arrange to ; save the position of the current script so that both begin ; with the same horizontal position. StorePos = '!S' RecallPos = '!R' LenLastScript = strlen(Script) - 2*strcnt(Script,'!') ENDIF ENDELSE ; Continue building the IDL string, adding on our just processed script. NewString = NewString + StorePos + FntChange + Script + RecallPos $ + FontRestore IF ( pos NE -1 ) THEN BEGIN ; more left to process NewString = NewString $ + str_token(strn, Token) ENDIF ELSE BEGIN ; we are done NewString = NewString + strn strn = '' ENDELSE ENDWHILE return, NewString END