source: trunk/SRC/Textoidl/translate_sub_super.pro @ 114

Last change on this file since 114 was 114, checked in by smasson, 18 years ago

new compilation options (compile_opt idl2, strictarrsubs) in each routine

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