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