[2] | 1 | ;+ |
---|
[232] | 2 | ; |
---|
[163] | 3 | ; @file_comments |
---|
| 4 | ; Return the proper IDL font positioning command for TeX |
---|
[226] | 5 | ; sub/superscripts. |
---|
[2] | 6 | ; |
---|
[163] | 7 | ; @categories |
---|
| 8 | ; Text, String |
---|
[2] | 9 | ; |
---|
[163] | 10 | ; @param TOKEN |
---|
| 11 | ; Either '^' or '_', the TeX super/subscript characters |
---|
| 12 | ; |
---|
| 13 | ; @keyword FORCE_UD |
---|
| 14 | ; Set this to use !U/!D instead of !E/!I for sub/superscripts. |
---|
| 15 | ; |
---|
| 16 | ; @returns |
---|
| 17 | ; Either '!U' or !E' for superscripts, or '!D' or '!I' for subscripts. |
---|
| 18 | ; |
---|
| 19 | ; @uses |
---|
| 20 | ; |
---|
| 21 | ; |
---|
| 22 | ; @restrictions |
---|
| 23 | ; Make sure sub_sup_idl stays before translate_sub_super. At least |
---|
| 24 | ; for now, when IDL encounters a function and automatically compiles |
---|
| 25 | ; it, it only compiles the functions in the file up to the named |
---|
| 26 | ; function. So even if sub_sup_idl was declared with |
---|
| 27 | ; FORWARD_FUNCTION in translate_sub_super, it would not properly |
---|
[226] | 28 | ; compile. |
---|
[163] | 29 | ; |
---|
| 30 | ; The file translate_sub_super.pro contains two functions, |
---|
| 31 | ; translate_sub_super, and sub_sup_idl. The former is the |
---|
| 32 | ; generic routine for processing TeX sub/superscripts, the |
---|
| 33 | ; latter is used only by translate_sub_super and has no general |
---|
| 34 | ; utility. Hence it lives here. You will see documentation for |
---|
| 35 | ; translate_sub_super second if you use DOC_LIBRARY. |
---|
| 36 | ; |
---|
| 37 | ; Used only by translate_sub_super. Should be kept in same |
---|
| 38 | ; file. |
---|
[226] | 39 | ; |
---|
[163] | 40 | ; @examples |
---|
| 41 | ; |
---|
| 42 | ; |
---|
| 43 | ; @history |
---|
[7] | 44 | ; $Log: translate_sub_super.pro,v $ |
---|
[47] | 45 | ; Revision 1.5 2000/06/14 19:09:22 mcraig |
---|
| 46 | ; Changed name of strtok str_token to avoid conflict in IDL 5.3. |
---|
| 47 | ; |
---|
[2] | 48 | ; Revision 1.4 1996/06/14 20:00:27 mcraig |
---|
| 49 | ; Updated Copyright info. |
---|
| 50 | ; |
---|
| 51 | ; Revision 1.3 1996/05/09 00:22:17 mcraig |
---|
| 52 | ; Changed some function calls to reflect changes in those functions, moved |
---|
| 53 | ; some code out of the main loop that didn't need to be there, added |
---|
| 54 | ; documentation. |
---|
| 55 | ; |
---|
| 56 | ; Revision 1.1 1996/01/31 18:47:37 mcraig |
---|
| 57 | ; Initial revision |
---|
| 58 | ; |
---|
| 59 | ; Copyright (C) 1996 The Regents of the University of California, All |
---|
| 60 | ; Rights Reserved. Written by Matthew W. Craig. |
---|
| 61 | ; See the file COPYRIGHT for restrictions on distrubting this code. |
---|
| 62 | ; This code comes with absolutely NO warranty; see DISCLAIMER for details. |
---|
[163] | 63 | ; |
---|
| 64 | ; @version |
---|
| 65 | ; $Id$ |
---|
[327] | 66 | ; |
---|
[2] | 67 | ;- |
---|
[327] | 68 | FUNCTION sub_sup_idl, token, FORCE_UD=force_ud |
---|
[114] | 69 | ; |
---|
| 70 | compile_opt idl2, strictarrsubs |
---|
| 71 | ; |
---|
[2] | 72 | |
---|
| 73 | ; provide help if needed. |
---|
| 74 | IF (n_params() NE 1) OR keyword_set(Help) THEN BEGIN |
---|
| 75 | offset = ' ' |
---|
| 76 | print, offset+'Return the proper IDL font positioning command for TeX' |
---|
| 77 | print, offset+'sub/superscripts. ' |
---|
| 78 | print, offset+'fnt = sub_sup_idl( strn )' |
---|
| 79 | print, offset+'Inputs:' |
---|
| 80 | print, offset+offset+"strn -- Either '^' or '_', the TeX super/subscript in" |
---|
| 81 | print, offset+offset+' characters' |
---|
| 82 | print, offset+'Keywords:' |
---|
| 83 | print, offset+offset+'/FORCE_UD -- Set this to use !U/!D instead of !E/!I for' |
---|
| 84 | print, offset+offset+' sub/superscripts .' |
---|
| 85 | print, offset+offset+'/HELP -- Set to print useful message and exit.' |
---|
| 86 | print, offset+'Outputs:' |
---|
| 87 | print, offset+offset+"fnt -- Either '!U' or !E' for superscripts, out" |
---|
| 88 | print, offset+offset+" or '!D' or '!I' for subscripts." |
---|
| 89 | return, -1 |
---|
[226] | 90 | ENDIF |
---|
[2] | 91 | |
---|
[226] | 92 | IF keyword_set(force_ud) THEN BEGIN |
---|
| 93 | IF (token EQ '^') THEN return, '!U' |
---|
[2] | 94 | IF (token EQ '_') THEN return, '!D' |
---|
| 95 | return, '' |
---|
| 96 | ENDIF ELSE BEGIN |
---|
[226] | 97 | IF (token EQ '^') THEN return, '!E' |
---|
[2] | 98 | IF (token EQ '_') THEN return, '!I' |
---|
| 99 | return, '' |
---|
| 100 | ENDELSE |
---|
[226] | 101 | |
---|
[2] | 102 | END |
---|
| 103 | |
---|
| 104 | ; |
---|
| 105 | ;+ |
---|
| 106 | ; NAME: |
---|
| 107 | ; TRANSLATE_SUB_SUPER |
---|
| 108 | ; PURPOSE: |
---|
| 109 | ; Translate TeX sub/superscripts to IDL sub/superscripts. |
---|
| 110 | ; CATEGORY: |
---|
| 111 | ; text/strings |
---|
| 112 | ; CALLING SEQUENCE: |
---|
| 113 | ; new = translate_sub_super( old ) |
---|
| 114 | ; INPUTS: |
---|
| 115 | ; old -- string to be translated from TeX to IDL. in |
---|
| 116 | ; KEYWORD PARAMETERS: |
---|
[226] | 117 | ; /RECURSED -- set if this function is being called |
---|
| 118 | ; recursively. |
---|
[2] | 119 | ; /HELP -- Set to print useful message and exit. |
---|
| 120 | ; OUTPUTS: |
---|
| 121 | ; new -- string old converted from TeX to IDL out |
---|
| 122 | ; COMMON BLOCKS: |
---|
| 123 | ; SIDE EFFECTS: |
---|
| 124 | ; NOTES: |
---|
| 125 | ; - For best results, when both a sub and superscript are used, |
---|
| 126 | ; place the shorter of the two first (e.g. 'N^{a}_{bbbb}' is |
---|
| 127 | ; better than 'N_{bbbb}^{a}'). |
---|
| 128 | ; - Single character sub/super scripts do not need to be |
---|
| 129 | ; protected by braces. |
---|
| 130 | ; - Sub/superscripts may be nested (e.g. 'N^{N_1^N}'). |
---|
| 131 | ; EXAMPLE: |
---|
| 132 | ; out = translate_sub_super( 'N^2_{big}' ) |
---|
| 133 | ; Then out='N!U2!N!Dbig!N' which looks like it should on the |
---|
[226] | 134 | ; display. |
---|
[2] | 135 | ; LIBRARY FUNCTIONS CALLED: |
---|
[47] | 136 | ; str_token -- Text/string (mcraig) |
---|
[2] | 137 | ; sub_sup_idl -- contained in this file |
---|
| 138 | ; MODIFICATION HISTORY: |
---|
| 139 | ; $Id$ |
---|
[7] | 140 | ; $Log: translate_sub_super.pro,v $ |
---|
[47] | 141 | ; Revision 1.5 2000/06/14 19:09:22 mcraig |
---|
| 142 | ; Changed name of strtok str_token to avoid conflict in IDL 5.3. |
---|
| 143 | ; |
---|
[2] | 144 | ; Revision 1.4 1996/06/14 20:00:27 mcraig |
---|
| 145 | ; Updated Copyright info. |
---|
| 146 | ; |
---|
| 147 | ; Revision 1.3 1996/05/09 00:22:17 mcraig |
---|
| 148 | ; Changed some function calls to reflect changes in those functions, moved |
---|
| 149 | ; some code out of the main loop that didn't need to be there, added |
---|
| 150 | ; documentation. |
---|
| 151 | ; |
---|
| 152 | ; Revision 1.2 1996/02/08 18:54:20 mcraig |
---|
| 153 | ; Changed default sub/superscript size to be !D/!U rather than !I/!E to |
---|
| 154 | ; improve readability of plat annotations. |
---|
| 155 | ; |
---|
| 156 | ; Revision 1.1 1996/01/31 18:47:37 mcraig |
---|
| 157 | ; Initial revision |
---|
| 158 | ; |
---|
| 159 | ; RELEASE: |
---|
[47] | 160 | ; $Name: Rel_2_1_2 $ |
---|
[2] | 161 | ; |
---|
| 162 | ; COPYRIGHT: |
---|
| 163 | ; Copyright (C) 1996 The Regents of the University of California, All |
---|
| 164 | ; Rights Reserved. Written by Matthew W. Craig. |
---|
| 165 | ; See the file COPYRIGHT for restrictions on distrubting this code. |
---|
| 166 | ; This code comes with absolutely NO warranty; see DISCLAIMER for details. |
---|
| 167 | ;- |
---|
[163] | 168 | FUNCTION translate_sub_super, InputString, $ |
---|
[2] | 169 | RECURSED=recursed, $ |
---|
| 170 | HELP=Help |
---|
[114] | 171 | ; |
---|
| 172 | compile_opt idl2, strictarrsubs |
---|
| 173 | ; |
---|
[2] | 174 | |
---|
| 175 | ; Return to caller if error. |
---|
| 176 | On_error, 2 |
---|
| 177 | |
---|
| 178 | ; Offer help if needed and/or desired |
---|
| 179 | IF (n_params() NE 1) OR keyword_set(help) THEN BEGIN |
---|
| 180 | offset = ' ' |
---|
| 181 | print, offset+'Translate TeX sub/superscripts to IDL sub/superscripts.' |
---|
| 182 | print, offset+'new = translate_sub_super( old )' |
---|
| 183 | print, offset+'Inputs:' |
---|
| 184 | print, offset+offset+'old -- string to be translated from TeX to IDL. in' |
---|
| 185 | print, offset+'Keywords:' |
---|
| 186 | print, offset+offset+'/RECURSED -- set if this function is being called ' |
---|
| 187 | print, offset+offset+' recursively. ' |
---|
| 188 | print, offset+offset+'/HELP -- Set to print useful message and exit.' |
---|
| 189 | print, offset+'Outputs:' |
---|
| 190 | print, offset+offset+'new -- string old converted from TeX to IDL out' |
---|
| 191 | print, offset+'Notes:' |
---|
| 192 | print, offset+offset+'- For best results, when both a sub and superscript are used,' |
---|
| 193 | print, offset+offset+" place the shorter of the two first (e.g. 'N^{a}_{bbbb}' is" |
---|
| 194 | print, offset+offset+" better than 'N_{bbbb}^{a}')." |
---|
| 195 | print, offset+offset+'- Single character sub/super scripts do not need to be' |
---|
| 196 | print, offset+offset+' protected by braces.' |
---|
| 197 | print, offset+offset+"- Sub/superscripts may be nested (e.g. 'N^{N_1^N}')." |
---|
| 198 | return, -1 |
---|
[226] | 199 | ENDIF |
---|
[2] | 200 | |
---|
| 201 | ; To allow for nested scripts, use !E/!I instead of !U/!D for scripts |
---|
| 202 | ; when called recursively. |
---|
| 203 | IF (NOT keyword_set(recursed)) THEN $ |
---|
| 204 | ud = 1 $ |
---|
| 205 | ELSE $ |
---|
| 206 | ud = 0 |
---|
| 207 | |
---|
| 208 | ; Return to the normal level after making sub/superscript unless we |
---|
| 209 | ; are recursed, which indicates we are processing a nested script. |
---|
| 210 | IF keyword_set(recursed) THEN fontRestore = '' ELSE fontRestore = '!N' |
---|
| 211 | |
---|
| 212 | ; Initialize vars for processing scripts. |
---|
[114] | 213 | SpcByte = (byte(' '))[0] ;We need the BYTE value for a space below. |
---|
[2] | 214 | strn = InputString |
---|
| 215 | pos = 0 |
---|
| 216 | StorePos = '' |
---|
| 217 | RecallPos = '' |
---|
| 218 | OldToken = '' |
---|
| 219 | LenLastScript = 0 |
---|
| 220 | |
---|
| 221 | ; Grab next sub/superscript. Token will be either '^' or '_'. |
---|
| 222 | ; RETURN if no scripts. |
---|
| 223 | Token = nexttok(strn, '^_', pos = pos) |
---|
| 224 | if pos EQ -1 then return, InputString ;nothing to process. |
---|
| 225 | |
---|
| 226 | FntChange = sub_sup_idl(Token) |
---|
| 227 | |
---|
| 228 | ; Our approach will be to grab the input string up to the next '^' or |
---|
| 229 | ; '_', then process the script we've found. |
---|
[47] | 230 | NewString=str_token(strn,Token) |
---|
[2] | 231 | |
---|
| 232 | WHILE strlen(strn) GT 0 DO BEGIN |
---|
| 233 | ; Grab first char of sub/superscript. |
---|
| 234 | Script = strmid(strn, 0, 1) |
---|
| 235 | EndOfScript = 0 ;Position of end of this script. |
---|
| 236 | IF (Script EQ '{') THEN BEGIN ; Scripts of more than 1 char. |
---|
[226] | 237 | EndOfScript = matchdelim(strn) |
---|
[2] | 238 | Script = translate_sub_super(strmid(strn, 1, EndOfScript-1), $ |
---|
| 239 | /recursed ) |
---|
[226] | 240 | ENDIF |
---|
| 241 | ; Grab rest of string _after_ the end of the script. |
---|
[2] | 242 | strn = strmid(strn, EndOfScript+1, $ |
---|
| 243 | strlen(strn)-EndOfScript-1) |
---|
| 244 | |
---|
| 245 | ; Find the next script and prepare for processing it. |
---|
| 246 | FntChange = sub_sup_idl(Token, FORCE_UD = ud) |
---|
| 247 | OldToken = Token |
---|
| 248 | Token = nexttok(strn, '^_', POS = pos) |
---|
| 249 | |
---|
| 250 | ; If the input is 'n^2_j', we want the '2' to be directly above |
---|
| 251 | ; the 'j', rather than having the 'j' below and to the right of |
---|
| 252 | ; the 2. In other words, we want the first below, not the second. |
---|
| 253 | ; 2 2 |
---|
| 254 | ; N N |
---|
| 255 | ; J J |
---|
| 256 | ; To accomplish this, we need to save the position at which we |
---|
| 257 | ; begin writing the 2 with a !S, and restore that position with a |
---|
| 258 | ; !R after writing the 2. The first section in the IF block below |
---|
| 259 | ; handles the 'J' above, the thing after the first script. We |
---|
| 260 | ; don't care if there is another script following. We also padd |
---|
| 261 | ; the second script with spaces if it is shorter than the first to |
---|
| 262 | ; make sure that whatever comes out after the scripts starts in |
---|
| 263 | ; the proper place. The worry is that without the spaces, the |
---|
| 264 | ; input 'N^{looong}_{s} + 1' will end up with the + starting right |
---|
| 265 | ; the 's' ends. |
---|
| 266 | IF (StorePos EQ '!S') THEN BEGIN |
---|
| 267 | StorePos = '' |
---|
| 268 | RecallPos = '' |
---|
[226] | 269 | ; calculate the difference in length between this script and the |
---|
[2] | 270 | ; previous stacked one, removing font change commands (crudely by |
---|
| 271 | ; guessing that the number of characters this takes is twice the |
---|
| 272 | ; number of exclamation points). The + 1 below is a kludge. I |
---|
| 273 | ; don't know why, but I need one extra space. |
---|
| 274 | NumSpaces = LenLastScript - (strlen(script) - 2*strcnt(Script,'!')) |
---|
| 275 | NumSpaces = (NumSpaces + 1) > 0 |
---|
| 276 | IF NumSpaces GT 0 THEN $ |
---|
| 277 | Script = Script + string( replicate(SpcByte, NumSpaces) ) |
---|
| 278 | ENDIF ELSE BEGIN |
---|
| 279 | IF (Token NE OldToken) AND (pos EQ 0) THEN BEGIN |
---|
[226] | 280 | ; The next script immediately follows this one. Arrange to |
---|
[2] | 281 | ; save the position of the current script so that both begin |
---|
| 282 | ; with the same horizontal position. |
---|
| 283 | StorePos = '!S' |
---|
| 284 | RecallPos = '!R' |
---|
| 285 | LenLastScript = strlen(Script) - 2*strcnt(Script,'!') |
---|
| 286 | ENDIF |
---|
[226] | 287 | ENDELSE |
---|
[2] | 288 | |
---|
| 289 | ; Continue building the IDL string, adding on our just processed script. |
---|
| 290 | NewString = NewString + StorePos + FntChange + Script + RecallPos $ |
---|
| 291 | + FontRestore |
---|
| 292 | |
---|
[226] | 293 | IF ( pos NE -1 ) THEN BEGIN ; more left to process |
---|
[2] | 294 | NewString = NewString $ |
---|
[226] | 295 | + str_token(strn, Token) |
---|
[2] | 296 | ENDIF ELSE BEGIN ; we are done |
---|
| 297 | NewString = NewString + strn |
---|
| 298 | strn = '' |
---|
| 299 | ENDELSE |
---|
[226] | 300 | ENDWHILE |
---|
| 301 | |
---|
[2] | 302 | return, NewString |
---|
| 303 | END |
---|
| 304 | |
---|
| 305 | |
---|
| 306 | |
---|
| 307 | |
---|