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

Last change on this file since 163 was 163, checked in by navarro, 18 years ago

header improvements : type of parameters and keywords, default values, spell checking + idldoc assistant (IDL online_help)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.3 KB
Line 
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;-
66FUNCTION 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   
100END
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;-
166FUNCTION 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
301END
302
303
304
305
Note: See TracBrowser for help on using the repository browser.