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

Last change on this file since 325 was 325, checked in by pinsard, 17 years ago

modification of some headers (+some corrections) to prepare usage of the new idldoc

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