~ubuntu-branches/debian/sid/tex4ht/sid

« back to all changes in this revision

Viewing changes to lit/xtpipes.tex

  • Committer: Bazaar Package Importer
  • Author(s): Kapil Hari Paranjape
  • Date: 2008-09-12 10:32:36 UTC
  • mfrom: (1.3.2 upstream) (3.1.9 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080912103236-tgw2q5g6f5hp2pnm
Tags: 20080701-2
* debian/patches/add_manpage.diff: Modified the man page
  to recommend that "mk4ht" be used for conversions other than
  from TeX/LaTeX to HTML. This is in response to #495768.
* debian/control: Replaced "sun-java5-jre" with "openjdk-6-jre-headless"
  in the "Suggests" field for "tex4ht-common". The latter java runtime
  seems to work with "xtpipes.jar" and the former is non-free.
  (Closes: #486482)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
% generalize -i attribute to accept multiple directories, like for -classpath
 
2
 
1
3
% htlatex xtpipes "xhtml,3,next" "" "-d./"
 
4
% htlatex xtpipes "xhtml,3,next,doc" "" "-d./"
 
5
% htlatex xtpipes "xhtml,3,next,win" 
 
6
% htlatex xtpipes "xhtml,3,next,win,doc" 
 
7
 
 
8
% gcj support these ``generics''  with a ``-5'' or ``-1.5'' switch
 
9
 
2
10
 
3
11
\documentclass{article}
4
12
   \usepackage{url} 
22
30
 
23
31
 
24
32
 
 
33
\def\CNT{0}  
 
34
\bgroup  
 
35
   \catcode`\^=7  
 
36
   \catcode`\^^M=13  %  
 
37
   \gdef\OP#1{%  
 
38
      \edef\temp{%  
 
39
        \noexpand\<#1\noexpand\><<<  
 
40
            \CNT  
 
41
        >>> %  
 
42
      } \temp % 
 
43
      \immediate\write15{...... \CNT\space #1}  
 
44
      \HAdvance\CNT by 1 %  
 
45
   }   %  
 
46
\egroup  
 
47
 
 
48
 
 
49
 
 
50
 
 
51
 
 
52
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
53
% \AddFile[optional: target file name; default: given file name]  
 
54
%         (optional: target home dir; default MYDIR)  
 
55
%         {file name}{dir}  
 
56
    
 
57
\ifOption{win} 
 
58
   {\def\mv{move }} 
 
59
   {\def\mv{mv }} 
 
60
 
 
61
\def\Slash{/} 
 
62
 
63
   \catcode`\/=0 
 
64
   \catcode`\\=12 
 
65
   /ifOption{win}{/gdef/Slash{\}}{} 
 
66
 
67
\def\SLASH{/} 
 
68
 
 
69
\def\AddFile{\futurelet\ext\AddFileA}     
 
70
\def\AddFileA{%     
 
71
   \if [\ext \def\ext[##1]{\def\ext{##1}\futurelet\dir\AddFileB}%     
 
72
   \else     \def\ext{\def\ext{}\futurelet\dir\AddFileB}\fi     
 
73
   \ext}        
 
74
\def\AddFileB{%     
 
75
   \if (\dir \def\dir(##1){\def\dir{##1}\AddFileC}%     
 
76
   \else     \def\dir{\let\dir\MYdir\AddFileC}\fi     
 
77
   \dir}     
 
78
 
 
79
 
 
80
\def\AddFileC#1#2{% 
 
81
   \expandafter\setStartDir \dir #2!%  
 
82
   \bgroup 
 
83
     \def\Slash{/}% 
 
84
     \xdef\EndDir{\ifx \dir\empty \else \dir\Slash\fi    
 
85
                #2\Slash 
 
86
             \ifx\ext\empty  
 
87
                  \if !#1!\else #1\fi 
 
88
             \else \ext\fi}% 
 
89
   \egroup 
 
90
   \MakeDir     
 
91
   \if !#1!\else    
 
92
      \Needs{"\mv #1\space \dir \Slash#2\Slash 
 
93
                    \ifx\ext\empty #1\else \ext\fi"}%     
 
94
   \fi   
 
95
}     
 
96
 
 
97
\ifOption{win} 
 
98
 
99
   \def\MakeDir{\relax     
 
100
      \expandafter \ifx  \csname !\StartDir\endcsname\relax     
 
101
         \expandafter\let\csname !\StartDir\endcsname=\empty     
 
102
         \Needs{"if NOT EXIST \StartDir \space mkdir \StartDir"}%          
 
103
      \fi     
 
104
      \ifx \EndDir\empty \else     
 
105
          \expandafter\AppendDir \EndDir////*%     
 
106
          \expandafter\MakeDir     
 
107
      \fi     
 
108
   }     
 
109
}{ 
 
110
   \def\MakeDir{\relax     
 
111
      \expandafter \ifx  \csname !\StartDir\endcsname\relax     
 
112
         \expandafter\let\csname !\StartDir\endcsname=\empty     
 
113
         \Needs{"mkdir \StartDir"}%          
 
114
      \fi     
 
115
      \ifx \EndDir\empty \else     
 
116
          \expandafter\AppendDir \EndDir////*%     
 
117
          \expandafter\MakeDir     
 
118
      \fi     
 
119
   }     
 
120
 
121
 
 
122
\def\AppendDir#1/#2/#3/*{%     
 
123
   \def\temp{#2}\ifx \temp\empty   
 
124
      \let\EndDir=\empty      
 
125
   \else     
 
126
      \edef\StartDir{\ifx \StartDir\empty\else   
 
127
                     \ifx \StartDir\SLASH \Slash \else   
 
128
                     \StartDir\Slash\fi   \fi  
 
129
                     #1}% 
 
130
      \def\EndDir{#2/#3}%     
 
131
      \expandafter\MakeDir 
 
132
   \fi     
 
133
}     
 
134
\def\setStartDir#1#2!{%  
 
135
    \def\StartDir{#1}\ifx\StartDir\SLASH\else  
 
136
    \def\StartDir{}\fi  
 
137
}  
 
138
 
 
139
 
 
140
 
 
141
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
 
142
% % \AddFile[optional: target file name; default: given file name]
 
143
% %         (optional: target home dir; default MYDIR)
 
144
% %         {file name}{dir}
 
145
%   
 
146
% \def\AddFile{\futurelet\ext\AddFileA}   
 
147
% \def\AddFileA{%   
 
148
%    \if [\ext \def\ext[##1]{\def\ext{##1}\futurelet\dir\AddFileB}%   
 
149
%    \else     \def\ext{\def\ext{}\futurelet\dir\AddFileB}\fi   
 
150
%    \ext}      
 
151
% \def\AddFileB{%   
 
152
%    \if (\dir \def\dir(##1){\def\dir{##1}\AddFileC}%   
 
153
%    \else     \def\dir{\let\dir\MYdir\AddFileC}\fi   
 
154
%    \dir}   
 
155
% \def\AddFileC#1#2{%   
 
156
%    \expandafter\setStartDir \dir #2!%
 
157
%    \edef\EndDir{\ifx \dir\empty \else \dir/\fi  
 
158
%                 #2/\ifx\ext\empty \if !#1!XXX\else #1\fi\else \ext\fi}\MakeDir   
 
159
%    \if !#1!\else  
 
160
%       \Needs{"mv #1\space \dir /#2/\ifx\ext\empty #1\else \ext\fi"}%   
 
161
%    \fi 
 
162
% }   
 
163
% \def\MakeDir{\relax   
 
164
%    \expandafter \ifx  \csname !\StartDir\endcsname\relax   
 
165
%       \expandafter\let\csname !\StartDir\endcsname=\empty   
 
166
%       \Needs{"mkdir \StartDir"}%        
 
167
%    \fi   
 
168
%    \ifx \EndDir\empty \else   
 
169
%        \expandafter\AppendDir \EndDir////*%   
 
170
%        \expandafter\MakeDir   
 
171
%    \fi   
 
172
% }   
 
173
% \def\AppendDir#1/#2/#3/*{%   
 
174
%    \def\temp{#2}\ifx \temp\empty  \let\EndDir=\empty    
 
175
%    \else   
 
176
%       \edef\StartDir{\ifx \StartDir\empty\else 
 
177
%                      \ifx \StartDir\SLASH /\else 
 
178
%                      \StartDir/\fi   \fi
 
179
%                      #1}\def\EndDir{#2/#3}%   
 
180
%    \fi   
 
181
% }   
 
182
% \def\setStartDir#1#2!{%
 
183
%     \def\StartDir{#1}\ifx\StartDir\SLASH\else
 
184
%     \def\StartDir{}\fi
 
185
% }
 
186
% \def\SLASH{/}
25
187
 
26
188
 
27
189
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
28
 
% \AddFile[optional: target file name; default: given file name]
29
 
%         (optional: target home dir; default MYDIR)
30
 
%         {file name}{dir}
31
 
  
32
 
\def\AddFile{\futurelet\ext\AddFileA}   
33
 
\def\AddFileA{%   
34
 
   \if [\ext \def\ext[##1]{\def\ext{##1}\futurelet\dir\AddFileB}%   
35
 
   \else     \def\ext{\def\ext{}\futurelet\dir\AddFileB}\fi   
36
 
   \ext}      
37
 
\def\AddFileB{%   
38
 
   \if (\dir \def\dir(##1){\def\dir{##1}\AddFileC}%   
39
 
   \else     \def\dir{\let\dir\MYdir\AddFileC}\fi   
40
 
   \dir}   
41
 
\def\AddFileC#1#2{%   
42
 
   \expandafter\setStartDir \dir #2!%
43
 
   \edef\EndDir{\ifx \dir\empty \else \dir/\fi  
44
 
                #2/\ifx\ext\empty \if !#1!XXX\else #1\fi\else \ext\fi}\MakeDir   
45
 
   \if !#1!\else  
46
 
      \Needs{"mv #1\space \dir /#2/\ifx\ext\empty #1\else \ext\fi"}%   
47
 
   \fi 
48
 
}   
49
 
\def\MakeDir{\relax   
50
 
   \expandafter \ifx  \csname !\StartDir\endcsname\relax   
51
 
      \expandafter\let\csname !\StartDir\endcsname=\empty   
52
 
      \Needs{"mkdir \StartDir"}%        
53
 
   \fi   
54
 
   \ifx \EndDir\empty \else   
55
 
       \expandafter\AppendDir \EndDir////*%   
56
 
       \expandafter\MakeDir   
57
 
   \fi   
58
 
}   
59
 
\def\AppendDir#1/#2/#3/*{%   
60
 
   \def\temp{#2}\ifx \temp\empty  \let\EndDir=\empty    
61
 
   \else   
62
 
      \edef\StartDir{\ifx \StartDir\empty\else 
63
 
                     \ifx \StartDir\SLASH /\else 
64
 
                     \StartDir/\fi   \fi
65
 
                     #1}\def\EndDir{#2/#3}%   
66
 
   \fi   
67
 
}   
68
 
\def\setStartDir#1#2!{%
69
 
    \def\StartDir{#1}\ifx\StartDir\SLASH\else
70
 
    \def\StartDir{}\fi
71
 
}
72
 
\def\SLASH{/}
 
190
 
 
191
 
73
192
\def\MYdir{work.dir}  
74
193
 
75
194
 
78
197
\expandafter\let\csname !/home\endcsname\empty
79
198
\expandafter\let\csname !/home/4\endcsname\empty
80
199
\expandafter\let\csname !/home/4/gurari\endcsname\empty
81
 
\expandafter\let\csname !/home/4/gurari/tex4ht.dir\endcsname\empty
82
 
\expandafter\let\csname !/home/4/gurari/tex4ht.dir/texmf\endcsname\empty
83
 
\expandafter\let\csname !/home/4/gurari/tex4ht.dir/texmf/tex4ht\endcsname\empty
 
200
\expandafter\let\csname !/home/4/gurari/xtpipes.dir\endcsname\empty
 
201
%\expandafter\let\csname !/home/4/gurari/tex4ht.dir/texmf\endcsname\empty
 
202
%\expandafter\let\csname !/home/4/gurari/xtpipes.dir\endcsname\empty
84
203
 
85
204
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
86
205
 
92
211
 
93
212
 
94
213
 
 
214
%%%%%%%%%%%%%%%%%%
 
215
\part{Core}
 
216
%%%%%%%%%%%%%%%%%%
 
217
 
95
218
 
96
219
%%%%%%%%%%%%%%%%%%
97
220
\section{Control}
104
227
 
105
228
 
106
229
\AtEndDocument{
107
 
   \OutputCodE\<xtpipes.java\>
108
 
   \OutputCodE\<Xtpipes.java\>
 
230
   \OutputCode[java]\<xtpipes.java\>  % double .java to avoid problems on MS
 
231
   \OutputCodE\<Xtpipes.java\>    
109
232
   \OutputCodE\<xtpipes.dtd\>
110
233
}
111
234
 
116
239
% "}
117
240
 
118
241
 
 
242
\ifOption{win} {}{
119
243
\AtEndDocument{\Needs{"
120
244
  cd work.dir
121
245
  ;
122
246
  javac -Xlint:unchecked xtpipes/*.java
123
 
        -d /home/4/gurari/tex4ht.dir/texmf/tex4ht/bin/.
 
247
        -d /home/4/gurari/xtpipes.dir/.
124
248
  ;
125
249
  javac -Xlint:unchecked xtpipes/*/*.java
126
 
        -d /home/4/gurari/tex4ht.dir/texmf/tex4ht/bin/.
 
250
        -d /home/4/gurari/xtpipes.dir/.
127
251
  ;
128
252
  javac -Xlint:unchecked xtpipes.java
129
 
        -d /home/4/gurari/tex4ht.dir/texmf/tex4ht/bin/.
 
253
        -d /home/4/gurari/xtpipes.dir/.
130
254
"}}
131
 
 
 
255
}
132
256
 
133
257
 
134
258
% \Needs{"cp xtpipes.dtd xtpipes.dtd.1"}
135
 
% \AddFile[xtpipes.dtd](/home/4/gurari/tex4ht.dir/texmf/tex4ht/bin){xtpipes.dtd.1}{xtpipes/lib}
136
 
\AddFile(/home/4/gurari/tex4ht.dir/texmf/tex4ht/bin){xtpipes.dtd}{xtpipes/lib}
137
 
 
138
 
 
139
 
% \Needs{" 
140
 
%   mv xtpipes.java work.dir/xtpipes/.
141
 
%   ;
142
 
%   mv Xtpipes.java work.dir/xtpipes/.
143
 
%   ;
144
 
%   cp xtpipes.dtd /home/4/gurari/tex4ht.dir/texmf/tex4ht/xttl/.
145
 
% "}
 
259
% \AddFile[xtpipes.dtd](/home/4/gurari/xtpipes.dir/xtpipes/bin){xtpipes.dtd.1}{xtpipes/lib}
 
260
 
 
261
 
 
262
\ifOption{win} { 
 
263
    \def\BIN{}
 
264
}{
 
265
    \def\BIN{(/home/4/gurari/xtpipes.dir)}
 
266
}
 
267
 
 
268
\expandafter\AddFile\BIN{xtpipes.dtd}{xtpipes\Slash lib}
146
269
 
147
270
 
148
271
\AddFile{Xtpipes.java}{xtpipes}
149
272
 
150
273
\<Xtpipes.java\><<<
151
 
// `version
152
274
package xtpipes;
 
275
/*
 
276
Xtpipes.java (`version)
 
277
*/
153
278
`<xtpipes imports`>
 
279
`<class XtpipesPrintWriter`>
154
280
public class Xtpipes {
155
 
   `<xtpipes members`>
 
281
   `<xtpipes fields`>
156
282
   `<static void main(String [])`>
 
283
   `<static void xtpipes(String [], OutputStream, PrintWriter)`>
 
284
   `<static Document getDOM(...)`>
157
285
   `<static void mainMethod(String [])`>
158
 
   `<static Document getDOM(...)`>
 
286
   `<static void execute( node )`>
159
287
   `<static String execute( node, xml )`>
160
 
   `<static void execute( node )`>
161
 
   `<static void instructionErr( node, e, num )`>
 
288
   `<static void instructionErr(...)`>
 
289
   `<static String serialize( dom )`>
 
290
   `<static void cleanXmlns( dom )`>
162
291
163
292
`<class XtpipesEntityResolver`>
164
293
>>>
165
294
 
166
 
\Needs{"mv xtpipes.java \MYdir/."}
 
295
\Needs{"\mv xtpipes.java.java \MYdir\Slash xtpipes.java"}
167
296
 
168
297
NOTE: We can not place Xtpipes.class and xtpipes.class at the same
169
298
directory because MS Windows get confused between the two.
198
327
 
199
328
 
200
329
 
201
 
\<xtpipes members\><<<
 
330
\<xtpipes fields\><<<
202
331
private static HashMap <String,Object> map;
203
332
private static boolean needScript;
204
333
>>>
218
347
 
219
348
 
220
349
\<xtpipes imports\><<<
 
350
// import xtpipes.util.InputObject;
 
351
// import xtpipes.util.FileInfo;
 
352
import java.net.URLConnection;
221
353
import java.io.*;
222
354
import java.lang.reflect.*;
223
355
import java.util.HashMap;
243
375
}
244
376
>>>
245
377
 
 
378
 
 
379
 
 
380
 
 
381
\<static void xtpipes(String [], OutputStream, PrintWriter)\><<<
 
382
public static void xtpipes(String [] args, 
 
383
                           OutputStream out,
 
384
                           PrintWriter log)
 
385
                                                throws Exception {
 
386
  `<init fields`>
 
387
  outPrintWriter = new XtpipesPrintWriter( out, true ); 
 
388
  logWriter = (log==null)? (new PrintWriter( System.err )) : log;
 
389
  mainMethod(args);
 
390
  outPrintWriter.flush();
 
391
}
 
392
>>>
 
393
 
 
394
 
 
395
 
 
396
 
 
397
\<xtpipes fields\><<<
 
398
private static boolean returnDom;
 
399
private static String result;
 
400
>>>
 
401
 
 
402
\<init fields\><<<
 
403
returnDom = false;
 
404
result = null;
 
405
>>>
 
406
 
 
407
 
 
408
\<static Document getDOM(...)\><<<
 
409
public static Document getDOM(String args[]) 
 
410
                               throws Exception {
 
411
  `<init fields`>
 
412
   returnDom = true;
 
413
   mainMethod(args);
 
414
   Document dom = null;
 
415
   if( result == null ){
 
416
     System.err.println(
 
417
       "--- xtpipes warning --- getDOM without <return name=\"...\"> from 4xt file: "
 
418
         + scriptFile );
 
419
   } else {
 
420
      try{
 
421
         byte [] bytes = result.getBytes("UTF-8");
 
422
         InputStream is =  new ByteArrayInputStream( bytes );
 
423
         dom = domBuilder.parse (is);
 
424
      } catch ( org.xml.sax.SAXParseException e ){
 
425
         if( Xtpipes.trace ){ 
 
426
            Xtpipes.logWriter.println( 
 
427
               "\n---------------------------------------------------\n"
 
428
                        + result +
 
429
               "\n---------------------------------------------------\n" ); 
 
430
         } 
 
431
         String s = "";
 
432
         `<s += input file name within args`>
 
433
         if( scriptFile != null ){ s += "    script file: " + scriptFile; }
 
434
         instructionErr( null,
 
435
            "parsing error: " + e.getMessage() +s, 21 );
 
436
      } catch ( Exception e ){
 
437
         instructionErr( null, e.toString(), 5 );
 
438
      }  
 
439
      `<close ml2xml files`>
 
440
   }
 
441
   return dom;
 
442
 
443
>>>
 
444
 
 
445
\<static Document getDOM(...)\><<<
 
446
public static Document getDOM(String s, String args[]) 
 
447
                                           throws Exception {
 
448
   `<init fields`>
 
449
   returnDom = true;
 
450
   inData = s;
 
451
   mainMethod(args);
 
452
   Document dom = null;
 
453
   if( result == null ){
 
454
     System.err.println(
 
455
       "--- xtpipes warning --- getDOM without"
 
456
         + " <return name=\"...\"> from 4xt file: "
 
457
         + scriptFile );
 
458
   } else {
 
459
      try{
 
460
         byte [] bytes = result.getBytes("UTF-8");
 
461
         InputStream is =  new ByteArrayInputStream( bytes );
 
462
         dom = domBuilder.parse (is);
 
463
      } catch ( org.xml.sax.SAXParseException e ){
 
464
         instructionErr( null, "improper xml: " + e.getMessage() 
 
465
           + "\n code starts with: "
 
466
           + result.substring(0, Math.min(100,result.length()))
 
467
         , 17 );
 
468
      } catch ( Exception e ){
 
469
         instructionErr( null, e.toString(), 6 );
 
470
      }  
 
471
      `<close ml2xml files`>
 
472
   }
 
473
   return dom;
 
474
 
475
>>>
 
476
 
 
477
 
 
478
\<static Document getDOM(...)\><<<
 
479
public static Document getDOM(String args[], PrintWriter log) 
 
480
                               throws Exception {
 
481
   logWriter = (log==null)? new PrintWriter( System.err ) : log;
 
482
   return getDOM(args);
 
483
}
 
484
>>>
 
485
 
 
486
\<static Document getDOM(...)\><<<
 
487
public static Document getDOM(String s, String args[], PrintWriter log) 
 
488
                                           throws Exception {
 
489
   logWriter = (log==null)? (new PrintWriter( System.err )) : log;
 
490
   return getDOM(s, args);
 
491
}
 
492
>>>
 
493
 
 
494
 
 
495
 
 
496
 
 
497
\<xtpipes fields\><<<
 
498
static PrintWriter logWriter = new PrintWriter( System.err );
 
499
>>>
 
500
 
 
501
 
 
502
 
 
503
 
 
504
%%%%%%%%%%%%%
 
505
\subsection{Core Entry Code}
 
506
%%%%%%%%%%%%%
 
507
g
 
508
 
246
509
\<static void mainMethod(String [])\><<<
247
 
public static void mainMethod(String args[]) throws Exception {
248
 
  `<process command line`>
 
510
private static void mainMethod(String args[]) throws Exception {
 
511
  try{
 
512
    `<command line vars`>
 
513
    `<process command line`>
 
514
  } catch (Exception e){
 
515
     instructionErr( null, e.getMessage(), e.getStackTrace(), 31 );       
 
516
  }
249
517
  try {
250
518
     DocumentBuilderFactory domFactory =
251
519
           DocumentBuilderFactory.newInstance();
255
523
     validatingDomBuilder.setEntityResolver(`<new EntityResolver()`>);
256
524
     validatingDomBuilder.setErrorHandler(`<new ErrorHandler()`>);
257
525
     `<xtpipes initialization`>
 
526
     `<scriptFile := entry script file name`>
258
527
     while( needScript ){
 
528
       if( scriptFile == null ){
 
529
          instructionErr( null, "Missing 4xt script file name", 32 ); 
 
530
       }
259
531
       `<search script file`>
260
 
       Document script = validatingDomBuilder.parse
261
 
//           (new File(scriptFile).toURL().toString());
262
 
           (scriptFile);
 
532
       Document script = validatingDomBuilder.parse(scriptFile);
263
533
       `<trace open script`>
264
534
       execute( script.getFirstChild() );
265
535
     }
283
553
} } 
284
554
>>>
285
555
 
286
 
\<xtpipes members\><<<
287
 
private static boolean returnDom;
288
 
private static String result;
289
 
>>>
290
 
 
291
 
\<init fields\><<<
292
 
returnDom = false;
293
 
result = null;
294
 
>>>
295
 
 
296
 
 
297
 
\<static Document getDOM(...)\><<<
298
 
public static Document getDOM(String args[]) 
299
 
                               throws Exception {
300
 
  `<init fields`>
301
 
   returnDom = true;
302
 
   mainMethod(args);
303
 
   Document dom = null;
304
 
   if( result == null ){
305
 
     System.err.println(
306
 
       "--- xtpipes warning --- getDOM without <return name=\"...\"> from 4xt file: "
307
 
         + scriptFile );
308
 
   } else {
309
 
      try{
310
 
         byte [] bytes = result.getBytes("UTF-8");
311
 
         InputStream is =  new ByteArrayInputStream( bytes );
312
 
         dom = domBuilder.parse (is);
313
 
      } catch ( org.xml.sax.SAXParseException e ){
314
 
         String s = "";
315
 
         `<s += err args`>
316
 
         if( scriptFile != null ){ s += "    script file: " + scriptFile; }
317
 
         instructionErr( null,
318
 
            "parsing error: " + e.getMessage() +s, 21 );
319
 
      } catch ( Exception e ){
320
 
         instructionErr( null, e.toString(), 5 );
321
 
   }  }
322
 
   return dom;
323
 
324
 
>>>
325
 
 
326
 
\<static Document getDOM(...)\><<<
327
 
public static Document getDOM(String s, String args[]) 
328
 
                                           throws Exception {
329
 
   `<init fields`>
330
 
   returnDom = true;
331
 
   inData = s;
332
 
   mainMethod(args);
333
 
   Document dom = null;
334
 
   if( result == null ){
335
 
     System.err.println(
336
 
       "--- xtpipes warning --- getDOM without <return name=\"...\"> from 4xt file: "
337
 
         + scriptFile );
338
 
   } else {
339
 
      try{
340
 
         byte [] bytes = result.getBytes("UTF-8");
341
 
         InputStream is =  new ByteArrayInputStream( bytes );
342
 
         dom = domBuilder.parse (is);
343
 
      } catch ( org.xml.sax.SAXParseException e ){
344
 
         instructionErr( null, "improper xml: " + e.getMessage() 
345
 
           + "\n code starts with: "
346
 
           + result.substring(0, Math.min(100,result.length()))
347
 
         , 17 );
348
 
      } catch ( Exception e ){
349
 
         instructionErr( null, e.toString(), 6 );
350
 
   }  }
351
 
   return dom;
352
 
353
 
>>>
354
 
 
355
 
 
356
 
\<static Document getDOM(...)\><<<
357
 
public static Document getDOM(String args[], PrintWriter log) 
358
 
                               throws Exception {
359
 
   logWriter = (log==null)? new PrintWriter( System.err ) : log;
360
 
   return getDOM(args);
361
 
}
362
 
>>>
363
 
 
364
 
\<static Document getDOM(...)\><<<
365
 
public static Document getDOM(String s, String args[], PrintWriter log) 
366
 
                                           throws Exception {
367
 
   logWriter = (log==null)? (new PrintWriter( System.err )) : log;
368
 
   return getDOM(s, args);
369
 
}
370
 
>>>
371
 
 
372
 
 
373
 
\<xtpipes members\><<<
374
 
static PrintWriter logWriter = new PrintWriter( System.err );
375
 
>>>
 
556
 
 
557
 
 
558
 
376
559
 
377
560
 
378
561
%%%%%%%%%%%%%
379
 
\subsection{Locate Script File}
 
562
\subsection{Locate the Script File}
380
563
%%%%%%%%%%%%%
381
564
 
382
565
 
383
566
 
384
567
 
385
568
\<search script file\><<<
386
 
String f = XtpipesEntityResolver.searchFile( scriptFile );
 
569
String f = FileInfo.searchFile( scriptFile );
387
570
if( f == null ){
388
571
   throw new java.io.FileNotFoundException( scriptFile );
389
572
} else {
417
600
 
418
601
 
419
602
\<static void execute( node )\><<<
420
 
static void execute( Node node ) throws Exception {
 
603
private static void execute( Node node ) throws Exception {
421
604
  while( node != null ){ 
422
605
    if( node.getNodeType()==Node.ELEMENT_NODE ){
423
606
      String instruction = node.getNodeName();
450
633
 
451
634
 
452
635
%%%%%%%%%%%%%
453
 
\subsection{Comamnd Line Options}
454
 
%%%%%%%%%%%%%
455
 
 
456
 
\<xtpipes members\><<<
457
 
private static String     inFile,
458
 
                          inData;
459
 
static String scriptDir, scriptFile;
460
 
static boolean exceptionErrs, messages;
461
 
>>>
462
 
 
463
 
 
464
 
\<init fields\><<<
465
 
inFile = null;
466
 
inData = null;
467
 
scriptFile = "xtpipes-default.4xt";
468
 
scriptDir = null;
469
 
exceptionErrs = false;
470
 
messages = false;
471
 
>>>
 
636
\subsection{Comamnd Line Options: Outline}
 
637
%%%%%%%%%%%%%
 
638
 
 
639
 
 
640
 
 
641
\<get args[n]\><<<
 
642
if( args[n] == null ){}
 
643
else if( args[n].equals("") ){}
 
644
else if( args[n].charAt(0)!='-' ){ inFile = args[n]; }
 
645
else if( args[n].equals("-m") ){ 
 
646
  messages = true;
 
647
  `<output system info`>
 
648
}
 
649
else if( args[n].equals("-s") ){ 
 
650
  `<scan script file name`>
 
651
}
 
652
else if( args[n].equals("-S") ){ 
 
653
  `<scan script map file name`>
 
654
}
 
655
else if( args[n].equals("-i") ){ 
 
656
  `<scan script dir name`>
 
657
}
 
658
else if( args[n].equals("-o") ){ 
 
659
  `<scan output file name`>
 
660
}
 
661
else if( args[n].startsWith("-x") ){ 
 
662
  `<scan ml2xml argument`>
 
663
}
 
664
else if( args[n].equals("-E") ){ 
 
665
  exceptionErrs = true;
 
666
}
 
667
else if( args[n].equals("-d") ){ 
 
668
  `<scan input data`>
 
669
}
 
670
else if( args[n].equals("-trace") ){ trace=true; }
 
671
else if( args[n].equals("-help") ){ help=true; }
 
672
else { `<improper args[n]`> }
 
673
>>>
 
674
 
 
675
 
 
676
\<display command line syntax\><<<
 
677
System.err.println( xtpipes_call );
 
678
>>>
 
679
 
 
680
\<command line vars\><<<
 
681
String xtpipes_call =
 
682
     "   xtpipes (`version)"
 
683
   + "\n   Command line options: " 
 
684
   + "\n     java xtpipes [-trace] [-help] [-m] [-E] [-s script_file]"
 
685
   +                                               " [-S script_map]"
 
686
   + "\n                  [-i script_dir] [-o out_file] "
 
687
   + "\n                  [-x...ml2xml_arg...]  "
 
688
   +                     "(-d in_data | in_file)"
 
689
   + "\n     -m        messages printing mode"
 
690
   + "\n     -E        error messages into exception calls"
 
691
   + "\n     in_data   XML data directly into the command line\n"
 
692
;
 
693
>>>
 
694
 
 
695
 
 
696
 
 
697
At least one  `-x'  command line option is required for ml2xml 
 
698
to be called.  An empty postfix is also fine.
 
699
 
 
700
 
 
701
 
 
702
\<s += input file name within args\><<<
 
703
for( int n=0; n<args.length; n++ ){
 
704
  if( args[n].charAt(0)!='-' ){
 
705
     s += "  input file: " + args[n] + ".";  break;
 
706
  } 
 
707
  else if( args[n].equals("-s")  
 
708
           || args[n].equals("-S")
 
709
           || args[n].equals("-i")
 
710
           || args[n].equals("-o") 
 
711
           || args[n].equals("-d") ){ n++;  }
 
712
}  
 
713
>>>
 
714
 
 
715
%%%%%%%%%%%%%
 
716
\subsection{Comamnd Line Options: Processing}
 
717
%%%%%%%%%%%%%
 
718
 
472
719
 
473
720
 
474
721
\<process command line\><<<
475
722
boolean help=false;
476
723
for( int n=0; n<args.length; n++ ){
477
 
  if( args[n].charAt(0)!='-' ){ inFile = args[n]; }
478
 
  else if( args[n].equals("-m") ){ 
479
 
    messages = true;
480
 
    logWriter.println("xtpipes (`version)");
481
 
  }
482
 
  else if( args[n].equals("-s") ){ 
483
 
    `<scan script file name`>
484
 
  }
485
 
  else if( args[n].equals("-i") ){ 
486
 
    `<scan script dir name`>
487
 
  }
488
 
  else if( args[n].equals("-o") ){ 
489
 
    `<scan output file name`>
490
 
  }
491
 
  else if( args[n].equals("-E") ){ 
492
 
    exceptionErrs = true;
493
 
  }
494
 
  else if( args[n].equals("-d") ){ 
495
 
    `<scan input data`>
496
 
  }
497
 
  else if( args[n].equals("-trace") ){ trace=true; }
498
 
  else if( args[n].equals("-help") ){ help=true; }
499
 
  else if( !args[n].equals("") ){
500
 
     System.err.println(
501
 
        "--- Error --- Improper argument: " + args[n] );
502
 
     inFile = null; inData = null; break;
503
 
} }
 
724
  `<get args[n]`>
 
725
}
504
726
`<default stdio output`>
 
727
`<help message and stop on improper args in batch mode`>
 
728
new FileInfo(logWriter, i_scriptDir, trace);
 
729
if( inFile != null ){
 
730
   inputObject = new InputObject( inFile, logWriter );
 
731
   if( inputObject.getInputStream() == null ){
 
732
      instructionErr( null, "Could not find or open file: " + inFile, 28 ); 
 
733
   }
 
734
   inFile = inputObject.getFilename();
 
735
} else {
 
736
   inputObject = new InputObject( inData.getBytes("UTF-8"), logWriter );
 
737
}
 
738
inputObject.buildProfile( trace );
 
739
>>>
 
740
 
 
741
\<help message and stop on improper args in batch mode\><<<
505
742
if( !returnDom ){
506
743
   if( help || ((inFile == null) && (inData == null)) ){
507
 
     System.err.println( 
508
 
          "   Command line options: " +
509
 
          "java xtpipes [-trace] [-help] [-m] [-E] [-s script_file]\n"
510
 
        + "    [-i script_dir] [-o out_file] "
511
 
        + "[-d in_data] in_file\n\n"
512
 
        + "     -m        messages printing mode\n"
513
 
        + "     -E        error messages into exception calls\n"
514
 
        + "     in_data   XML data directly into the command line\n"
515
 
     );
 
744
     `<display command line syntax`>
516
745
     if( (inFile == null) && (inData == null) ){
517
746
        System.exit(0);
518
747
}  } }
519
748
>>>
520
749
 
521
 
\<scan script file name\><<<
522
 
n++;
523
 
if( n < args.length ){ scriptFile=args[n]; }
524
 
else {
525
 
  System.err.println(
526
 
      "--- Error --- Missing field for -s argument" );
527
 
  inFile = null; inData = null;  break;
528
 
}
529
 
>>>
530
 
 
531
 
 
532
 
 
533
 
\<scan script dir name\><<<
534
 
n++;
535
 
if( n < args.length ){ 
536
 
   scriptDir=args[n]; 
537
 
} else {
538
 
  System.err.println(
539
 
      "--- Error --- Missing field for -s argument" );
540
 
  inFile = null; inData = null; break;
541
 
}
542
 
>>>
543
 
 
 
750
\<improper args[n]\><<<
 
751
if( !exceptionErrs ){
 
752
  for(int i=n+1; i<args.length; i++ ){
 
753
    if( args[i].equals("-E") ){ exceptionErrs = true; }
 
754
} }
 
755
instructionErr( null, 
 
756
     "Improper argument: " + args[n] + "\n" + xtpipes_call, 26 );
 
757
>>>
544
758
 
545
759
 
546
760
 
561
775
 
562
776
 
563
777
 
564
 
 
565
 
 
566
 
 
567
 
 
568
 
 
569
 
 
570
 
 
571
 
 
572
 
 
573
 
 
574
 
 
575
 
 
576
 
 
577
 
 
578
 
\<s += err args\><<<
579
 
for( int n=0; n<args.length; n++ ){
580
 
  if( args[n].charAt(0)!='-' ){
581
 
     s += "  input file: " + args[n] + ".";  break;
582
 
  } 
583
 
  else if( args[n].equals("-s")  
584
 
           || args[n].equals("-i")
585
 
           || args[n].equals("-o") 
586
 
           || args[n].equals("-d") ){ n++;  }
587
 
}  
588
 
>>>
589
 
 
590
 
 
591
 
 
592
 
 
 
778
\<xtpipes fields\><<<
 
779
private static String     inFile,
 
780
                          inData;
 
781
private static boolean exceptionErrs, messages;
 
782
public static InputObject inputObject;
 
783
>>>
 
784
 
 
785
 
 
786
\<init fields\><<<
 
787
inFile = null;
 
788
inData = null;
 
789
exceptionErrs = false;
 
790
messages = false;
 
791
>>>
593
792
 
594
793
 
595
794
%%%%%%%%%%%%% 
596
 
\subsubsection{Ouput File}
 
795
\subsection{Ouput File}
597
796
%%%%%%%%%%%%% 
598
797
 
599
798
 
625
824
>>>
626
825
 
627
826
 
628
 
\<xtpipes members\><<<
629
 
static String outFileName;
630
 
static PrintWriter outPrintWriter;
631
 
static boolean returnToFile = false;
 
827
\<xtpipes fields\><<<
 
828
private static String outFileName;
 
829
private static PrintWriter outPrintWriter;
 
830
private static boolean returnToFile = false;
632
831
>>>
633
832
 
634
833
\<init fields\><<<
661
860
}
662
861
>>>
663
862
 
664
 
\<xtpipes imports\><<<
 
863
\<class XtpipesPrintWriter\><<<
665
864
class XtpipesPrintWriter extends PrintWriter {
666
865
   public XtpipesPrintWriter() {
667
866
     super(System.out, true);
669
868
   public XtpipesPrintWriter (PrintStream ps, boolean b){
670
869
     super(ps, b);
671
870
   }
 
871
   public XtpipesPrintWriter (OutputStream ps, boolean b){
 
872
     super(ps, b);
 
873
   }
672
874
   public XtpipesPrintWriter (FileWriter fw){
673
875
     super(fw);
674
876
   } 
680
882
}  } 
681
883
>>>
682
884
 
683
 
%%%%%%%%%%%%%%%%%%
684
 
\section{The Instructions}
685
 
%%%%%%%%%%%%%%%%%%
686
 
 
687
 
 
688
 
 
689
 
%%%%%%%%%%%%% 
690
 
\subsection{XtPipes}
691
 
%%%%%%%%%%%%% 
 
885
 
 
886
 
 
887
 
 
888
 
 
889
%%%%%%%%%%%%%%%%%%
 
890
\section{The xtpipes Script}
 
891
%%%%%%%%%%%%%%%%%%
 
892
 
 
893
 
 
894
The translation of a file is driven by a script that determines the
 
895
transformations to be applied to the diffrent fragments of the input
 
896
data.  The name of the script may be found in different locations.
 
897
 
 
898
\begin{itemize}
 
899
\item
 
900
A xtpipes processing instruction within the input
 
901
\item
 
902
Command line option `-s'
 
903
\item
 
904
A .map  file that checks the data characteristics to determine the
 
905
script. Currently available only to input files, not to input strings.
 
906
\end{itemize}
 
907
 
 
908
 
 
909
 
 
910
%%%%%%%%%%%%%
 
911
\subsection{Command Line Options}
 
912
%%%%%%%%%%%%%
 
913
 
 
914
 
 
915
A script should satisfy  the rules of `xtpipes.dtd',
 
916
and a map should satisfy the rules of `xtpipes-map.dtd'.
 
917
 
 
918
 
 
919
 
 
920
 
 
921
\<scan script file name\><<<
 
922
n++;
 
923
if( n < args.length ){ scriptFile=args[n]; }
 
924
else {
 
925
  System.err.println(
 
926
      "--- Error --- Missing field for -s argument" );
 
927
  inFile = null; inData = null;  break;
 
928
}
 
929
>>>
 
930
 
 
931
 
 
932
\<scan script map file name\><<<
 
933
n++;
 
934
if( n < args.length ){ scriptMap=args[n]; }
 
935
else {
 
936
  System.err.println(
 
937
      "--- Error --- Missing field for -S argument" );
 
938
  inFile = null; inData = null;  break;
 
939
}
 
940
>>>
 
941
 
 
942
 
 
943
\<scan script dir name\><<<
 
944
n++;
 
945
if( n < args.length ){ 
 
946
   i_scriptDir=args[n]; 
 
947
} else {
 
948
  System.err.println(
 
949
      "--- Error --- Missing field for -i argument" );
 
950
  inFile = null; inData = null; break;
 
951
}
 
952
>>>
 
953
 
 
954
 
 
955
 
 
956
 
 
957
\<xtpipes fields\><<<
 
958
public static String scriptFile;
 
959
private static String scriptMap;
 
960
static String i_scriptDir;
 
961
>>>
 
962
 
 
963
 
 
964
\<init fields\><<<
 
965
scriptFile = null;
 
966
i_scriptDir = null;
 
967
scriptMap = null;
 
968
>>>
 
969
 
 
970
 
 
971
 
 
972
 
 
973
%%%%%%%%%%%%%
 
974
\subsection{Getting the Start Up Script}
 
975
%%%%%%%%%%%%%
 
976
 
 
977
The command line arguments may provide a pointer to 
 
978
a `scriptFile' and a pointer to an algorithm `scriptMap'
 
979
for getting the script file name.
 
980
 
 
981
With and without ml2xml
 
982
 
 
983
\<scriptFile := entry script file name\><<<
 
984
if( scriptMap != null ){
 
985
   try{
 
986
      String f = FileInfo.searchFile( scriptMap );
 
987
      if( f == null ){
 
988
         throw new java.io.FileNotFoundException( scriptMap );
 
989
      } else {
 
990
         scriptMap = f;
 
991
      }
 
992
      `<get sax reader`>        
 
993
      saxReader.setContentHandler( new DefaultHandler(){
 
994
         `<process script map`>
 
995
        } );
 
996
      InputStream inputStream =
 
997
           (InputStream) (new File(scriptMap).toURI().toURL().openStream());
 
998
      saxReader.parse( new InputSource(inputStream) );
 
999
      saxReaderStack.push( saxReader );
 
1000
   } catch( java.io.FileNotFoundException e ){ 
 
1001
      instructionErr( null, 
 
1002
                      "File not found: " + e.getMessage()
 
1003
                      + "; command line option -i",
 
1004
                      33 );   
 
1005
   } catch( Exception e ){ 
 
1006
      instructionErr( null, e.toString(), e.getStackTrace(), 27 ); 
 
1007
   }
 
1008
}
 
1009
if( scriptFile == null ){
 
1010
    scriptFile = "xtpipes-default.4xt";
 
1011
}
 
1012
>>>
 
1013
 
 
1014
 
 
1015
\<process script map\><<<
 
1016
private Stack <Boolean> condition = new Stack <Boolean> ();
 
1017
>>>
 
1018
 
 
1019
\<process script map\><<<
 
1020
public void startDocument () {
 
1021
   condition.push( new Boolean(true) );
 
1022
}
 
1023
>>>
 
1024
 
 
1025
\<process script map\><<<
 
1026
public void startElement(String ns, String sName,
 
1027
                        String qName, Attributes atts) {
 
1028
   if( condition == null ){ return; }
 
1029
   `<trace start map element`>
 
1030
   boolean cond = ((Boolean) condition.peek()).booleanValue();
 
1031
   if( qName.equals("when") ){
 
1032
      if( cond ){ `<cond := when ...`> }
 
1033
   }
 
1034
   else 
 
1035
   if( qName.equals("command-line") ){
 
1036
      if( scriptFile != null ){ 
 
1037
        `<trace found script in map`>
 
1038
        condition = null;
 
1039
        return;
 
1040
   }  }
 
1041
   else 
 
1042
   if( qName.equals("processing-instruction") ){
 
1043
      if( cond ){ 
 
1044
         String s = inputObject.getXtpipes();
 
1045
         if( s != null ){
 
1046
           Xtpipes.scriptFile = s;
 
1047
           `<trace found script in map`>
 
1048
           condition = null;
 
1049
           return;
 
1050
   }  }  }
 
1051
   else 
 
1052
   if( qName.equals("select") ){
 
1053
      if( cond ){ 
 
1054
        Xtpipes.scriptFile = atts.getValue("name");
 
1055
        `<trace found script in map`>
 
1056
        condition = null;
 
1057
        return;
 
1058
   }  }
 
1059
   condition.push( new Boolean(cond) );
 
1060
}
 
1061
>>>
 
1062
 
 
1063
 
 
1064
 
 
1065
 
 
1066
\<process script map\><<<
 
1067
public void endElement(String ns, String sName, String qName) {
 
1068
   if( condition == null ){ return; }
 
1069
   `<trace end map element`>
 
1070
   condition.pop();
 
1071
}
 
1072
>>>
 
1073
 
 
1074
 
 
1075
 
 
1076
\<cond := when ...\><<<
 
1077
String name = atts.getValue("name");
 
1078
String value = atts.getValue("value");
 
1079
if( name.equals("system-id") ){
 
1080
   cond = value.equals(inputObject.getSystemId());
 
1081
}                
 
1082
else                 
 
1083
if( name.equals("public-id") ){
 
1084
   cond = value.equals(inputObject.getPublicId());
 
1085
}   
 
1086
else
 
1087
if( name.equals("dtd-root") ){
 
1088
   cond = value.equals(inputObject.getDtdRoot());
 
1089
}     
 
1090
else
 
1091
if( name.equals("root") ){
 
1092
   cond = value.equals(inputObject.getRoot());
 
1093
}        
 
1094
else
 
1095
if( name.equals("ext") ){
 
1096
   cond = inputObject.getFilename().endsWith("." + value);
 
1097
}         
 
1098
else
 
1099
if( name.equals("prefix") ){
 
1100
   name = inputObject.getFilename();
 
1101
   if( name != null ){
 
1102
      int i = name.lastIndexOf('/');
 
1103
      if( (i != -1) && ((i+1) < name.length()) ){
 
1104
         name = name.substring(i+1); 
 
1105
      }
 
1106
      i = name.lastIndexOf('\\');
 
1107
      if( (i != -1) && ((i+1) < name.length()) ){
 
1108
         name = name.substring(i+1); 
 
1109
      }
 
1110
      cond = name.startsWith(value);
 
1111
}  }
 
1112
else
 
1113
if( name.equals("meta-type") ){
 
1114
   cond = value.equals(inputObject.getMetaType());
 
1115
}        
 
1116
else
 
1117
if( name.equals("content-type") ){
 
1118
   cond = value.equals(inputObject.getContentType());
 
1119
 
1120
>>>
 
1121
 
 
1122
 
 
1123
 
 
1124
 
 
1125
 
 
1126
 
 
1127
 
 
1128
\<trace found script in map\><<<
 
1129
if( trace ){
 
1130
   Xtpipes.logWriter.println( " Found script file in map: "
 
1131
                                + Xtpipes.scriptFile );
 
1132
}
 
1133
>>>
 
1134
 
 
1135
 
 
1136
\<trace start map element\><<< 
 
1137
if( Xtpipes.trace ){
 
1138
   String s =  "<" + qName + "\n";
 
1139
   for(int i=0; i<atts.getLength(); i++ ){
 
1140
      String name = atts.getQName(i);
 
1141
      s += " " + name + "=\"" + atts.getValue(i) + "\"";
 
1142
   } 
 
1143
   s += ">" ;
 
1144
   Xtpipes.logWriter.println( s );
 
1145
}
 
1146
>>>
 
1147
 
 
1148
\<trace end map element\><<<
 
1149
if( Xtpipes.trace ){
 
1150
   String s =  "</" + qName + ">";
 
1151
   Xtpipes.logWriter.println( s );
 
1152
}
 
1153
>>>
 
1154
 
 
1155
 
 
1156
 
 
1157
%%%%%%%%%%%%%
 
1158
\subsection{DTDs}
 
1159
%%%%%%%%%%%%%
 
1160
 
 
1161
 
 
1162
 
 
1163
%%%%%%%%%%%%%
 
1164
\immediate\openin15=xtpipes.dtd
 
1165
\ifeof15 \else
 
1166
   \immediate\closein15
 
1167
   [\HPage{xtpipes.dtd}
 
1168
     \verbatiminput{xtpipes.dtd}
 
1169
   \EndHPage{}]
 
1170
\fi
 
1171
%%%%%%%%%%%%%
 
1172
%
 
1173
%%%%%%%%%%%%%
 
1174
\immediate\openin15=xtpipes-map.dtd
 
1175
\ifeof15 \else
 
1176
   \immediate\closein15
 
1177
   [\HPage{xtpipes-map.dtd}
 
1178
     \verbatiminput{xtpipes-map.dtd}
 
1179
   \EndHPage{}]
 
1180
\fi
 
1181
%%%%%%%%%%%%%
692
1182
 
693
1183
\begin{verbatim}
694
1184
<xtpipes> ... </xtpipes>
701
1191
          signature CDATA #IMPLIED                         >
702
1192
>>>
703
1193
 
704
 
If the element has no children, the input file is searched for an
705
 
alternative script within a processing instruction of the form
706
 
\verb+<?xtpipes file="..." ?>+.
707
 
 
708
 
 
709
 
\<execute xtpipes\><<<
710
 
String errMsg = "";
711
 
needScript = false;
712
 
if( node.hasChildNodes() ){
713
 
  `<open output file`>
714
 
  `<cond copy input preamble`>
715
 
   execute( node.getFirstChild() );
 
1194
 
 
1195
 
 
1196
\AtEndDocument{
 
1197
   \OutputCodE\<xtpipes-map.dtd\>
 
1198
}
 
1199
 
 
1200
\expandafter\AddFile\BIN{xtpipes-map.dtd}{xtpipes\Slash lib}
 
1201
 
 
1202
  
 
1203
\<xtpipes-map.dtd\><<<  
 
1204
<!-- xtpipes-map.dtd (`version) -->  
 
1205
<!ELEMENT xtpipes-map (when | processing-instruction  
 
1206
                            | select
 
1207
                            | command-line)*  >  
 
1208
<!ELEMENT when (when | select
 
1209
                     | processing-instruction  
 
1210
                     | command-line )*  >  
 
1211
<!ELEMENT select EMPTY >  
 
1212
<!ELEMENT processing-instruction EMPTY >  
 
1213
<!ELEMENT command-line EMPTY >  
 
1214
<!ATTLIST xtpipes-map
 
1215
          signature      CDATA #IMPLIED  
 
1216
>  
 
1217
<!ATTLIST when  
 
1218
          name   (
 
1219
                    system-id                                 
 
1220
                  | public-id   
 
1221
                  | dtd-root     
 
1222
                  | root        
 
1223
                  | ext         
 
1224
                  | meta-type        
 
1225
                  | content-type 
 
1226
                  | prefix      )  "public-id"
 
1227
          value   CDATA #IMPLIED  
 
1228
          case-sensitive (yes|no) "no"  
 
1229
>  
 
1230
<!ATTLIST select  
 
1231
          name      CDATA #REQUIRED  
 
1232
>  
 
1233
>>>  
 
1234
 
 
1235
 
 
1236
%%%%%%%%%%%%%
 
1237
\subsection{Indirect Scripts}
 
1238
%%%%%%%%%%%%%
 
1239
 
 
1240
 
 
1241
 
 
1242
If the root xtpipes element has no children, the input file is
 
1243
searched for an alternative script within a processing instruction of
 
1244
the form \verb+<?xtpipes file="..." ?>+.
 
1245
 
 
1246
\<script := xtpipes processing instruction\><<<
 
1247
if( inData == null ){
 
1248
   `<search file for xtpipes instruction`>
716
1249
} else {
717
 
   try{
718
 
      `<get sax reader`>      
719
 
      saxReader.setContentHandler( new XtPipesSearch() );
720
 
      if( inData == null ){
721
 
         `<search file for xtpipes instruction`>
722
 
      } else {
723
 
         `<search string for xtpipes instruction`>
724
 
      }
725
 
      saxReaderStack.push( saxReader );
726
 
   } catch(Exception e){   
727
 
      instructionErr( node, errMsg + e.toString(), 13 );   
728
 
}  }
 
1250
   `<search string for xtpipes instruction`>
 
1251
}
729
1252
>>>
730
1253
 
731
1254
 
 
1255
%%%%%%%%%%%%%
 
1256
\subsection{Search File}
 
1257
%%%%%%%%%%%%%
 
1258
 
 
1259
 
732
1260
 
733
1261
 
734
1262
\<search file for xtpipes instruction\><<<
735
 
errMsg = "Searching <?xtpipes file=\"...\"?>  in "
736
 
                      + inFile + ": ";
 
1263
/*
 
1264
errMsg = "Searching <?xtpipes file=\"...\"?>  in "
 
1265
                      + inFile + ": ";
 
1266
*/
 
1267
scriptFile = inputObject.getXtpipes();
 
1268
rootName = inputObject.getRoot();
 
1269
needScript = true;
 
1270
>>>
 
1271
 
 
1272
\<search file for xtpipes instructionOLD\><<<
 
1273
errMsg = "Searching <?xtpipes file=\"...\"?>  in "
 
1274
                      + inFile + ": ";
 
1275
       `<get sax reader`>      
 
1276
       saxReader.setContentHandler( new XtPipesSearch() );
737
1277
try{
738
 
    saxReader.parse( new File(inFile).toURL().toString() );
 
1278
    saxReader.parse( new File(inFile).toURI().toURL().toString() );
739
1279
} catch ( java.io.FileNotFoundException ioe ){           
740
1280
    try{
741
1281
       saxReader.parse( new InputSource(
742
1282
                        new URL(inFile) . openStream() ));  
743
1283
    } catch ( java.io.FileNotFoundException fnf ){           
744
 
        saxReader.parse( new File(inFile).toURL().toString() );         
 
1284
        saxReader.parse( new File(inFile).toURI().toURL().toString() );         
745
1285
}   } 
746
 
>>>
747
 
 
748
 
 
749
 
 
750
 
\<search string for xtpipes instruction\><<<
751
 
errMsg = "Searching <?xtpipes file=\"...\"?>  in "
752
 
        + inData.substring(0, Math.min(70,inData.length()))
753
 
        + "... : ";
754
 
byte [] bytes = inData.getBytes("UTF-8");
755
 
ByteArrayInputStream bais = new ByteArrayInputStream( bytes );
756
 
InputSource is = new InputSource( bais );
757
 
saxReader.parse(is);
758
 
>>>
759
 
 
760
 
 
761
 
 
762
 
 
763
 
 
764
 
 
765
 
 
766
 
\<xtpipes members\><<<
767
 
static class XtPipesSearch extends DefaultHandler {
768
 
   public void  endElement(String uri, 
769
 
                           String localName, String qName){
770
 
     `<extract root element name`>
771
 
   }
772
 
   public void processingInstruction(String target, String attrs) {
773
 
     if( !needScript && target.equals("xtpipes") ){
774
 
        `<extract script file name`>
775
 
}  } }
776
 
>>>
777
 
 
778
 
 
779
 
 
780
 
\<xtpipes members\><<<
781
 
private static String  rootName;
782
 
>>>
783
 
 
784
 
 
785
 
\<init fields\><<<
786
 
rootName = null;
787
 
>>>
788
 
 
789
 
\<extract root element name\><<<
790
 
rootName = qName;
791
 
>>>
792
 
 
793
 
 
794
 
\<extract script file name\><<<
795
 
try {
796
 
   `<get sax reader`>      
797
 
   saxReader.setContentHandler(new DefaultHandler() { 
798
 
      public void startElement(String uri, String localName, 
799
 
         String qName, Attributes atts) { 
800
 
         String filename = atts.getValue("file");
801
 
         if( filename != null ){
802
 
            scriptFile = filename;
803
 
            if( messages ){
804
 
               logWriter.println(
805
 
                  "Requesting XtPipes script file: "
806
 
                  + filename );
807
 
            }
808
 
            needScript = true;
809
 
      }  }
810
 
   }); 
811
 
   String str = "<xtpipes " + attrs + "/>"; 
812
 
   StringReader reader = new StringReader(str); 
813
 
   InputSource in = new InputSource(reader); 
814
 
   saxReader.parse(in); 
815
 
   saxReaderStack.push( saxReader );
816
 
} catch(Exception e){ 
817
 
   System.err.println( "--- Error 10 --- " + e ); 
818
 
 
1286
       saxReaderStack.push( saxReader );
819
1287
>>>
820
1288
 
821
1289
%%%%%%%%%%%%% 
822
1290
\subsection{Copy Preamble}
823
1291
%%%%%%%%%%%%% 
824
1292
 
 
1293
 
 
1294
Copy into th eoutput the code preceeding the root. Note: assumes proper 
 
1295
XML file as it doesn't use ml2xml. NEEDS FIXING.
 
1296
Example:
 
1297
 
 
1298
\begin{verbatim}
 
1299
----> <?xml version="1.0" encoding="UTF-8"?>  
 
1300
----> <!DOCTYPE math:math PUBLIC "-//W3C//DTD MathML 2.0//EN" "math.dtd">  
 
1301
----> <?xtpipes file="oo-math.4xt" ?>  
 
1302
----> <!-- try-m12 by TeX4ht from try.tex line 69 2007-01-09-11:20  
 
1303
----> (http://www.cse.ohio-state.edu/~gurari/TeX4ht/) -->  
 
1304
\end{verbatim}
 
1305
 
 
1306
 
 
1307
 
825
1308
\<cond copy input preamble\><<<
826
1309
if( node.hasAttributes() ){
827
1310
   Node attr = node.getAttributes()
828
1311
                   .getNamedItem( "signature" );
829
 
   if ( (attr != null) && messages ) {
830
 
      logWriter.println( attr.getNodeValue() );
831
 
   }
 
1312
   `<preamble output into log`>
832
1313
   attr = node.getAttributes()
833
1314
                   .getNamedItem( "preamble" );
834
1315
   if( (attr != null) 
839
1320
 
840
1321
 
841
1322
\<get src preamble\><<<
842
 
BufferedReader br = null;
 
1323
// BufferedReader br = null;
843
1324
try {
844
1325
   String s;
845
 
   boolean front = true;
846
 
   rootName = "<" + rootName;
 
1326
   boolean front = true;   
 
1327
   rootName = "<" + ((rootName==null)? inputObject.getRoot() : rootName);
847
1328
   if( inData == null ){
848
1329
      `<get src preamble from file`>
849
1330
   } else {
856
1337
>>>
857
1338
 
858
1339
 
 
1340
 
 
1341
 
859
1342
\<get src preamble from file\><<<
860
 
FileReader fr = new FileReader(inFile);
861
 
BufferedReader in = new BufferedReader(fr);
 
1343
// FileReader fr = new FileReader(inFile);
 
1344
// BufferedReader in = new BufferedReader(fr);
 
1345
`<BufferedReader in := inFile`>
862
1346
while (  ((s = in.readLine()) != null) && front ) {
863
1347
   int i = s.indexOf( rootName );
864
1348
   if( i > -1 ){
871
1355
in.close();
872
1356
>>>
873
1357
 
 
1358
\<BufferedReader in := inFile\><<<
 
1359
URLConnection connection = 
 
1360
             new URL(inFile).openConnection();
 
1361
connection.setRequestProperty("User-Agent",
 
1362
                "["
 
1363
              + System.getProperty("os.name")
 
1364
              + " / "
 
1365
              + System.getProperty("os.arch")
 
1366
              + "]"
 
1367
              + "["
 
1368
              + System.getProperty("java.version")
 
1369
              + " - "
 
1370
              + System.getProperty("java.vendor")
 
1371
              + "]"
 
1372
);
 
1373
InputStream inputStream = connection.getInputStream();
 
1374
BufferedReader in = new BufferedReader (
 
1375
                        new InputStreamReader ( inputStream ) );
 
1376
>>>
 
1377
 
 
1378
 
 
1379
 
 
1380
 
874
1381
 
875
1382
 
876
1383
\<get src preamble from string\><<<
884
1391
>>>
885
1392
 
886
1393
 
 
1394
 
 
1395
 
 
1396
%%%%%%%%%%%%%%%%%%
 
1397
\section{The Instructions}
 
1398
%%%%%%%%%%%%%%%%%%
 
1399
 
 
1400
 
 
1401
 
 
1402
%%%%%%%%%%%%% 
 
1403
\subsection{XtPipes}
 
1404
%%%%%%%%%%%%% 
 
1405
 
 
1406
The xtpipes element is the root of the script file through which 
 
1407
the transformation starts.
 
1408
 
 
1409
\<execute xtpipes\><<<
 
1410
// String errMsg = "";
 
1411
needScript = false;
 
1412
if( node.hasChildNodes() ){
 
1413
  `<open output file`>
 
1414
  `<cond copy input preamble`>
 
1415
   execute( node.getFirstChild() );
 
1416
} else {
 
1417
   `<script := xtpipes processing instruction`>
 
1418
}  
 
1419
>>>
 
1420
 
 
1421
 
 
1422
 
 
1423
 
 
1424
 
 
1425
 
 
1426
If the root xtpipes element has no children, the input file is
 
1427
searched for an alternative script within a processing instruction of
 
1428
the form \verb+<?xtpipes file="..." ?>+.
 
1429
 
 
1430
 
 
1431
 
 
1432
 
 
1433
 
887
1434
%%%%%%%%%%%%% 
888
1435
\subsection{Handle Set}
889
1436
%%%%%%%%%%%%% 
977
1524
\<xtpipes initialization\><<<
978
1525
fc = TransformerFactory.newInstance();
979
1526
identityTransformer =  fc.newTransformer();  
 
1527
identityTransformer.setErrorListener( 
 
1528
    `<identity transformer XML error listener`> );
980
1529
>>>
981
1530
 
982
 
\<xtpipes members\><<<
983
 
static TransformerFactory fc;
984
 
static Transformer identityTransformer;
 
1531
\<xtpipes fields\><<<
 
1532
private static TransformerFactory fc;
 
1533
private static Transformer identityTransformer;
985
1534
>>>
986
1535
 
987
1536
 
1024
1573
                 .getNamedItem( "name" ).getNodeValue();
1025
1574
String xml = (String) map.get(name);
1026
1575
if( node.getAttributes().getNamedItem( "file" )==null ){
1027
 
   System.err.println( XtpipesUni.toUni(xml, "") );
 
1576
   if( !Xtpipes.trace ){
 
1577
      logWriter.println( "[##]  = xtpipes => print: " + scriptFile );
 
1578
   }
 
1579
   logWriter.println( XtpipesUni.toUni(xml, "") );
1028
1580
} else {
1029
1581
   String file = node.getAttributes()
1030
1582
                 .getNamedItem( "file" ).getNodeValue();
1127
1679
                 .getNamedItem( "xml" ).getNodeValue();
1128
1680
String dtd = node.getAttributes()
1129
1681
                 .getNamedItem( "dtd" ).getNodeValue();
1130
 
String root = node.getAttributes()
1131
 
                 .getNamedItem( "root" ).getNodeValue();
 
1682
// String root = node.getAttributes()
 
1683
//                 .getNamedItem( "root" ).getNodeValue();
1132
1684
String doc = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
1133
1685
             + "<!DOCTYPE doc [\n"
1134
1686
             + (String) map.get(dtd) 
1144
1696
>>>
1145
1697
 
1146
1698
 
1147
 
\<xtpipes members\><<<
1148
 
static SAXParserFactory saxFactory;
 
1699
\<xtpipes fields\><<<
 
1700
private static SAXParserFactory saxFactory;
1149
1701
>>>
1150
1702
 
1151
1703
 
1190
1742
   `<StreamSource inDoc = ...`>
1191
1743
   `<StreamSource inXslt = ...`>
1192
1744
   `<StreamResult outDoc = ...`>
1193
 
   fc.setErrorListener( `<transformer error listener`> );
 
1745
   errMssg = null;
 
1746
   fc.setErrorListener( `<transformer factory XSLT error listener`> );
1194
1747
   Transformer transformer = fc.newTransformer( inXslt );
 
1748
   transformer.setErrorListener( `<transformer XML error listener`> ); 
1195
1749
   transformer.transform(inDoc, outDoc ); 
1196
1750
   `<store xslt outcome`>
 
1751
} catch ( javax.xml.transform.TransformerException e ){
 
1752
   if( Xtpipes.trace ){ e.printStackTrace(); }
 
1753
   instructionErr( node, 
 
1754
                   e.getMessage()
 
1755
                   + 
 
1756
                   ((errMssg==null)? "" : ("; " +errMssg))
 
1757
                   , 37);
1197
1758
} catch ( Exception e ){  
1198
 
   instructionErr( node, e.toString(), 16 );   
 
1759
   if( Xtpipes.trace ){ e.printStackTrace(); }
 
1760
   instructionErr( node, (errMssg==null)? e.toString() 
 
1761
                                        : e.toString() + "; " + errMssg
 
1762
                       , 16 );   
1199
1763
1200
1764
>>>
1201
1765
 
1327
1891
          xml    CDATA #REQUIRED 
1328
1892
          method CDATA #REQUIRED 
1329
1893
          class  CDATA #REQUIRED 
 
1894
          dcl    CDATA #IMPLIED DEFAULT (yes | no) "no"
1330
1895
>
1331
1896
>>>
1332
1897
 
 
1898
 
 
1899
 
1333
1900
\<execute dom\><<<
1334
1901
try{ 
1335
1902
   `<load xml into dom`>
1338
1905
} catch ( NoSuchMethodException e ){  
1339
1906
   instructionErr( node, 
1340
1907
       "could not find method: " + e.getMessage(), 18 );   
 
1908
} catch ( java.lang.reflect.InvocationTargetException e ){
 
1909
   if( Xtpipes.trace ){ e.printStackTrace(); }
 
1910
   instructionErr( node, e.getCause().toString(), 36);
1341
1911
} catch ( Exception e ){  
 
1912
   if( Xtpipes.trace ){ e.printStackTrace(); }
1342
1913
   instructionErr( node, e.toString(), 20 );   
1343
1914
1344
1915
>>>
1355
1926
             .getNamedItem( "class" ).getNodeValue();
1356
1927
String methodName = node.getAttributes()
1357
1928
             .getNamedItem( "method" ).getNodeValue();
1358
 
Class cls = Class.forName( className );
1359
 
Class [] argTypes = { Node.class }; 
 
1929
Class <?> cls = Class.forName( className );
 
1930
Class<?>  [] argTypes = { Node.class }; 
1360
1931
Method m = cls.getMethod( methodName, argTypes ); 
1361
1932
Object parmValues[] = new Object[1]; 
1362
1933
parmValues[0] = dom; 
1368
1939
domBuilder = domFactory.newDocumentBuilder();
1369
1940
>>>
1370
1941
 
1371
 
\<xtpipes members\><<<
1372
 
static DocumentBuilder domBuilder;
 
1942
\<xtpipes fields\><<<
 
1943
private static DocumentBuilder domBuilder;
1373
1944
>>>
1374
1945
 
1375
1946
 
1414
1985
 
1415
1986
\<store dom into map\><<<
1416
1987
`<StreamResult outDoc = ...`>
1417
 
identityTransformer.transform( new DOMSource(dom), outDoc );
 
1988
cleanXmlns(dom);
 
1989
DOMSource domSource = new DOMSource(dom);
 
1990
try{   
 
1991
   identityTransformer.transform( domSource, outDoc );
 
1992
} catch ( javax.xml.transform.TransformerException e ){
 
1993
  String s = Xtpipes.trace?
 
1994
      (
 
1995
        "\n------------------------ xml code ------------------------\n"
 
1996
      + serialize( dom )
 
1997
      + "\n----------------------------------------------------------\n"
 
1998
      )
 
1999
      : "";
 
2000
   instructionErr( node, e.getMessage() + s, 35 );
 
2001
}
1418
2002
if( nameNode != null ){
1419
2003
  String name = nameNode.getNodeValue();
1420
2004
  char [] chars = caos.toCharArray() ;
1421
 
  map.put( name, (Object) new String(chars) );
1422
 
}
1423
 
>>>
 
2005
  String domString = new String(chars);
 
2006
  `<remove dom dcl`>
 
2007
  map.put( name, (Object) domString );
 
2008
}
 
2009
>>>
 
2010
 
 
2011
 
 
2012
\<remove dom dcl\><<<
 
2013
Node dcl = node.getAttributes().getNamedItem( "dcl" );
 
2014
if(  ((dcl == null) || (dcl.getNodeValue().equals("no") ))
 
2015
     &&
 
2016
       (domString.length() > 7)
 
2017
     &&
 
2018
       domString.startsWith("<?xml")
 
2019
     &&
 
2020
       !Character.isLetterOrDigit( domString.charAt(5) )
 
2021
){
 
2022
    domString = domString.substring( domString.indexOf("?>") + 2 );
 
2023
}
 
2024
>>>
 
2025
 
 
2026
 
 
2027
 
 
2028
 
 
2029
 
1424
2030
 
1425
2031
\<NO\><<<
1426
2032
String name = node.getAttributes()
1434
2040
 
1435
2041
 
1436
2042
 
1437
 
 
1438
 
 
1439
2043
%%%%%%%%%%%%%
1440
2044
\subsection{Handle SAX}
1441
2045
%%%%%%%%%%%%%
1449
2053
content.
1450
2054
 
1451
2055
\begin{verbatim}
1452
 
<sax name="..." xml="..." content-handler="..." >
 
2056
<sax name="..." xml="..." content-handler="..." 
 
2057
                          lexical-handler="..." >
1453
2058
   <script element="..." > ... </script>
1454
2059
   ...
1455
2060
   <script element="..." > ... </script>
1467
2072
 
1468
2073
The \verb+content-handler+ attribute gets a comma seperated list of
1469
2074
classes names. The first argument refers to a content handler, the
1470
 
other arguments rfefer to filters.
1471
 
 
 
2075
other arguments refer to filters. A content handler gets five
 
2076
arguments: output stream,
 
2077
an HashMap refering to the different scripts enclosed by the sax
 
2078
instruction,
 
2079
a method,
 
2080
log stream, and a boolean trace indicator.
 
2081
A filter and a lexical-constractor gets three arguments: output
 
2082
stream, log stream, and a boolean trace indicator.
1472
2083
 
1473
2084
 
1474
2085
 
1512
2123
            + className[0].trim() + " )";
1513
2124
   saxReader.setContentHandler( (org.xml.sax.ContentHandler) ch );
1514
2125
   `<saxReader += lexical handler`>
1515
 
`%
1516
 
   org.xml.saxInterface.EntityResolver savedER = saxReader.getEntityResolver();
1517
 
`%
1518
2126
   `<saxReader := ignore DOCTYPE statement`>
1519
2127
   if( inputSource==null ){
1520
2128
       `<open sax input file`>
1521
2129
   } else {
1522
 
       errMsg = "xttl sax parsing error";
 
2130
       errMsg = "xtpipes sax parsing error";
1523
2131
       saxReader.parse( inputSource );
1524
2132
   }
1525
2133
   `<store chars into map`>
1526
 
`% 
1527
 
   reader.setEntityResolver(savedER);
1528
 
`%
1529
 
  saxReaderStack.push( reader );
 
2134
   saxReaderStack.push( reader );
1530
2135
} catch ( java.io.FileNotFoundException e ){ 
1531
2136
   instructionErr( node, errMsg 
1532
2137
                   + "could not find file: " + e.getMessage(), 19 );  
1533
2138
} catch ( ClassNotFoundException e ){ 
1534
 
   instructionErr( node, errMsg + e.toString() + "\n classpath = "
1535
 
                   + System.getProperty("java.class.path"), 22 );  
 
2139
   instructionErr( node, errMsg 
 
2140
                   + " class not found: "
 
2141
                   + e.getMessage() + "\n classpath = "
 
2142
                   + System.getProperty("java.class.path")
 
2143
                   + " ---", 22 );  
 
2144
} catch ( java.lang.reflect.InvocationTargetException e ){ 
 
2145
   instructionErr( node, errMsg + ": " + e.getCause(), 23 );  
1536
2146
} catch ( Exception e ){ 
1537
 
   instructionErr( node, errMsg + e.toString(), 22 );  
 
2147
// e.printStackTrace();
 
2148
   instructionErr( node, errMsg + e.toString(), 29 );  
1538
2149
}
1539
2150
>>>
1540
2151
 
1541
2152
\<open sax input file\><<<
1542
2153
errMsg = "While parsing file " + xml + ": ";
 
2154
InputStream inputStream = null;            
 
2155
if( Xtpipes.ml2xml == null ){
 
2156
   if( Xtpipes.trace ){
 
2157
       Xtpipes.logWriter.println( 
 
2158
         "No request for ml2xml configuration (command line option -x)" ); 
 
2159
   }
 
2160
   `<inputStream := ml2xml-less imput`>
 
2161
} else {
 
2162
   `<inputStream := (InputStream) new Ml2xml(filename, "foo.m2x")`>
 
2163
}
 
2164
saxReader.parse( new InputSource(inputStream) );
 
2165
`<Ml2xml close files`>
 
2166
>>>
 
2167
 
 
2168
\<inputStream := ml2xml-less imput\><<<
1543
2169
try{
1544
 
    saxReader.parse( new File(xml).toURL().toString() );
 
2170
    inputStream = (InputStream) (new File(xml).toURI().toURL().openStream());  
1545
2171
} catch ( java.io.FileNotFoundException ioe ){           
1546
2172
    try{
1547
2173
       URL url = null;
1548
2174
       try {
1549
2175
           url = new URL(xml);
1550
2176
       } catch ( java.net.MalformedURLException fnf ){           
1551
 
           url = new File(xml).toURL();
 
2177
           url = new File(xml).toURI().toURL();
1552
2178
       }
1553
 
       saxReader.parse( new InputSource( url . openStream() ));  
 
2179
       inputStream = (InputStream) (url.openStream());  
1554
2180
    } catch ( java.io.FileNotFoundException fnf ){           
1555
 
       saxReader.parse( new File(xml).toURL().toString() );         
1556
 
}   } 
 
2181
        inputStream = (InputStream)
 
2182
           (
 
2183
              new File( new File(xml).toURI().toURL().toString() )
 
2184
              . toURI().toURL()
 
2185
              . openStream()
 
2186
           );  
 
2187
}   }
1557
2188
>>>
1558
2189
 
1559
2190
 
1560
2191
 
 
2192
 
 
2193
 
1561
2194
%%%%%%%%%%%%%
1562
2195
\subsubsection{SAX Reader}
1563
2196
%%%%%%%%%%%%%
1587
2220
saxFactory.setValidating(false);
1588
2221
>>>
1589
2222
 
1590
 
\<xtpipes members\><<<
1591
 
static Stack <XMLReader> saxReaderStack;
 
2223
\<xtpipes fields\><<<
 
2224
private static Stack <XMLReader> saxReaderStack;
1592
2225
>>>
1593
2226
 
1594
2227
 
1642
2275
InputSource inputSource=null;
1643
2276
String xml = null;
1644
2277
if( xmlNode == null ){
1645
 
   `<load xml fron input`>
 
2278
   `<load xml from input`>
1646
2279
} else {
1647
2280
   xml = xmlNode.getNodeValue();
1648
2281
   String doc = (String) map.get(xml);
1654
2287
>>>
1655
2288
 
1656
2289
 
1657
 
\<load xml fron input\><<<
 
2290
\<load xml from input\><<<
1658
2291
if( inData == null ){
1659
2292
   xml = inFile;
1660
2293
} else {
1708
2341
 
1709
2342
 
1710
2343
 
1711
 
The constructor of a content handler is provided three arguments:
 
2344
The constructor of a content handler is provided five arguments:
1712
2345
 
1713
2346
\begin{itemize}
1714
2347
\item
1716
2349
\item
1717
2350
A hash map containing the enclosed defdinitions of scripts 
1718
2351
\item A method name
 
2352
\item A log stream
 
2353
\item A trace flag
1719
2354
\end{itemize}
1720
2355
 
1721
2356
 
1722
2357
\<ch := content handler\><<<
1723
 
Class [] argTypes = {
1724
 
         PrintWriter.class, HashMap.class, Method.class }; 
 
2358
Class<?> [] argTypes = {
 
2359
         PrintWriter.class, HashMap.class, Method.class,
 
2360
         PrintWriter.class, boolean.class }; 
1725
2361
`<output stream for sax`>
1726
 
Object parmValues[] = new Object[3]; 
 
2362
Object parmValues[] = new Object[5]; 
1727
2363
parmValues[0] = out; 
1728
2364
`<sax scripts`>  parmValues[1] = scripts; 
1729
2365
parmValues[2] = method; 
1730
 
Class cls = Class.forName( className[0].trim() );
1731
 
Constructor c = cls.getConstructor( argTypes ); 
 
2366
parmValues[3] = Xtpipes.logWriter; 
 
2367
parmValues[4] = (Object) Xtpipes.trace; 
 
2368
Class<?> cls = Class.forName( className[0].trim() );
 
2369
Constructor<?> c = cls.getConstructor( argTypes ); 
1732
2370
Object ch = (Object) c.newInstance( parmValues );   
1733
2371
>>>
1734
2372
 
1750
2388
>>>
1751
2389
 
1752
2390
\<xtpipes initialization\><<<
1753
 
Class cls = Xtpipes.class;
1754
 
Class [] argTypes = { Node.class, String.class }; 
 
2391
Class <?> cls = Xtpipes.class;
 
2392
Class<?> [] argTypes = { Node.class, String.class }; 
1755
2393
method = cls.getMethod( "execute", argTypes ); 
1756
2394
>>>
1757
2395
 
1758
 
\<xtpipes members\><<<
1759
 
static Method method;
 
2396
\<xtpipes fields\><<<
 
2397
private static Method method;
1760
2398
>>>
1761
2399
 
1762
2400
%%%%%%%%%%%%%
1767
2405
 
1768
2406
\<insert sax filters\><<<
1769
2407
for( int i=1; i<className.length; i++ ){
1770
 
   argTypes = new Class [1];
 
2408
   argTypes = new Class [3];
1771
2409
   argTypes[0] = PrintWriter.class; 
1772
 
   parmValues = new Object[1]; 
 
2410
   argTypes[1] = PrintWriter.class;  
 
2411
   argTypes[2] = boolean.class; 
 
2412
   parmValues = new Object[3]; 
1773
2413
   parmValues[0] = out; 
 
2414
   parmValues[1] = Xtpipes.logWriter; 
 
2415
   parmValues[2] = (Object) Xtpipes.trace; 
1774
2416
   errMsg = "Class.forName( " + className[i].trim() + ") " ;
1775
2417
   cls = Class.forName( className[i].trim() );
1776
 
   errMsg = "get-constructor " + 
1777
 
               className[i].trim() + "( PrintWriter ) " ;
 
2418
   errMsg = "get-constructor "  
 
2419
            + className[i].trim()
 
2420
            + "( PrintWriter, PrintWriter, boolean ) " ;
1778
2421
   c = cls.getConstructor( argTypes ); 
1779
 
   errMsg = "get-instance " + 
1780
 
               className[i].trim() + "( PrintWriter ) " ;
 
2422
   errMsg = "get-object " 
 
2423
            + className[i].trim() 
 
2424
            + "( PrintWriter, PrintWriter, boolean ) " ;
 
2425
   if( (cls.getModifiers() % 2) != 1 ){
 
2426
      errMsg += "; class not defined to be public. ";
 
2427
   }
1781
2428
   XMLFilter filter = (XMLFilter) c.newInstance( parmValues );   
1782
 
   errMsg = "set-parent " + 
1783
 
               className[i].trim() + "( PrintWriter ) " ;
 
2429
   errMsg = "set-parent " 
 
2430
            +  className[i].trim() 
 
2431
            + "( PrintWriter, PrintWriter, boolean ) " ;
1784
2432
   filter.setParent(saxReader);
1785
2433
   saxReader = filter;
1786
2434
}
1787
2435
>>>
1788
2436
 
1789
2437
 
1790
 
The filters are assumed to have a single-parameter constructors which
1791
 
get output streams for arguments.
1792
 
 
1793
 
 
1794
 
% //   cls = Class.forName( className[i].trim() );
1795
 
% //   XMLFilter filter = (XMLFilter) cls.newInstance();      
1796
 
 
 
2438
The filters are assumed to have a tri-parameter constructors which
 
2439
get an output stream for first arguments, log stream for second argument, and 
 
2440
a trace boolean value for third argument.
1797
2441
 
1798
2442
 
1799
2443
 
1819
2463
                  .getNamedItem( "lexical-handler" );
1820
2464
if( lexAttr != null ){
1821
2465
   String lexName = lexAttr.getNodeValue();   
1822
 
   argTypes = new Class[1]; 
 
2466
   argTypes = new Class[3]; 
1823
2467
   argTypes[0] = Class.forName( className[0].trim() ); 
1824
 
   parmValues = new Object[1]; 
 
2468
   argTypes[1] = PrintWriter.class;  
 
2469
   argTypes[2] = boolean.class; 
 
2470
   parmValues = new Object[3]; 
1825
2471
   parmValues[0] = ch; 
 
2472
   parmValues[1] = Xtpipes.logWriter; 
 
2473
   parmValues[2] = (Object) Xtpipes.trace; 
1826
2474
   errMsg = "Class.forName( " + lexName.trim() + ") " ;
1827
2475
   cls = Class.forName( lexName.trim() );
1828
2476
   errMsg = "get-constructor " + 
1829
2477
                lexName.trim() +
1830
2478
                "( " + className[0].trim() + " ) " ;
1831
2479
   c = cls.getConstructor( argTypes ); 
1832
 
   errMsg = "get-instance " + 
 
2480
   errMsg = "get-object " + 
1833
2481
               lexName.trim() + "( ... ) " ;
1834
2482
   Object xh = (Object) c.newInstance( parmValues );   
1835
2483
   errMsg = "set lexical handler " + lexName.trim() + " ";  
1847
2495
 
1848
2496
 
1849
2497
 
1850
 
%%%%%%%%%%%%%%%%%%
1851
 
\section{Generic Content Handler}
1852
 
%%%%%%%%%%%%%%%%%%
1853
 
 
1854
 
 
1855
 
%%%%%%%%%%%%%
1856
 
\subsection{Outline}
1857
 
%%%%%%%%%%%%%
1858
 
 
1859
 
\label{ScriptsManager}
1860
 
 
1861
 
\AtEndDocument{
1862
 
   \OutputCodE\<ScriptsManager.java\>
1863
 
}
1864
 
\AddFile{ScriptsManager.java}{xtpipes/lib}
1865
 
 
1866
 
 
1867
 
\<ScriptsManager.java\><<<
1868
 
// `version
1869
 
package xtpipes.lib;
1870
 
import xtpipes.XtpipesUni;
1871
 
 
1872
 
import org.xml.sax.helpers.DefaultHandler;
1873
 
import org.xml.sax.*;     
1874
 
import java.io.*;     
1875
 
import java.lang.reflect.*;
1876
 
import java.util.HashMap;
1877
 
import java.util.Stack; 
1878
 
 
1879
 
public class ScriptsManager extends DefaultHandler {
1880
 
     `<ScriptsManager vars`>
1881
 
     PrintWriter out = null;
1882
 
     HashMap scripts = null;
1883
 
     Method method = null;
1884
 
     boolean savemode=false;
1885
 
     String code="", match = null;
1886
 
     Stack<Object[]> stack = new Stack<Object[]>();
1887
 
   public ScriptsManager( PrintWriter out, 
1888
 
                          HashMap scripts, Method method ){
1889
 
     this.out = out;
1890
 
     this.scripts = scripts;
1891
 
     this.method = method;
1892
 
   }
1893
 
   public void characters(char[] ch, int start, int length){
1894
 
     add( XtpipesUni.toUni(ch, start, length, "<>&") );
1895
 
   }
1896
 
   `<ScriptsManager: void startElement(ns, sName, qName, atts)`>
1897
 
   `<ScriptsManager: void endElement(ns, sName, qName)`>
1898
 
   public void add(String s){
1899
 
      if( savemode ){ code+=s; }
1900
 
      else { out.print(s); }
1901
 
}  }
1902
 
>>>
1903
 
 
1904
 
 
1905
 
 
1906
 
%%%%%%%%%%%%%
1907
 
\subsection{Start Elements}
1908
 
%%%%%%%%%%%%%
1909
 
 
1910
 
 
1911
 
 
1912
 
 
1913
 
\<ScriptsManager: void startElement(ns, sName, qName, atts)\><<<
1914
 
public void startElement(String ns, String sName,
1915
 
                        String qName, Attributes atts) {
1916
 
   inBody = true;
1917
 
   String s =  "<" + qName + "\n";
1918
 
   for(int i=0; i<atts.getLength(); i++ ){
1919
 
      String name = atts.getQName(i);
1920
 
      if( name != "xmlns" ){
1921
 
         s += " " + name + "=\"" + 
1922
 
         XtpipesUni.toUni(atts.getValue(i), "<>&\"") + "\"";
1923
 
   }  }
1924
 
   s += ">" ;
1925
 
   `<flag := start new save?`>
1926
 
   `<set start element`>
1927
 
}
1928
 
>>>
1929
 
 
1930
 
 
1931
 
\<ScriptsManager vars\><<<
1932
 
boolean inBody = false;
1933
 
>>>
1934
 
 
1935
 
 
1936
 
\<flag := start new save?\><<<
1937
 
String key = (atts==null)?
1938
 
               null 
1939
 
             : (qName + "::" + atts.getValue("class"));
1940
 
boolean flag = (key != null) && scripts.containsKey(key);
1941
 
 
1942
 
if( !flag ){
1943
 
   key = qName;
1944
 
   flag = scripts.containsKey(key);
1945
 
}
1946
 
>>>
1947
 
 
1948
 
\<set start element\><<<
1949
 
if( flag ){ 
1950
 
   Object [] state = { new Boolean(savemode), code, match }; 
1951
 
   stack.push( state );
1952
 
   savemode=true; code=""; match= key;
1953
 
} else {
1954
 
   Object [] state = { new Boolean(savemode), null, null }; 
1955
 
   stack.push( state );
1956
 
}
1957
 
add( s );
1958
 
>>>
1959
 
 
1960
 
The parsing of an XML string is similar to that of done by a
1961
 
left-to-right bottom up parser of a programming language.
1962
 
Specifically, the token are read and send on to the output stream,
1963
 
until an element whose name appears in the hash table of scripts is
1964
 
encountered.  When such an element is encountered, its body is
1965
 
assembled and the corresponding script is applied on the body.  The
1966
 
processing might be recursive, in the sense that enclosed elements
1967
 
might also have scripts to process them.
1968
 
 
1969
 
The above applies also to an element name concatenated with its class
1970
 
attribute value, with the substring `::' as a separator.
1971
 
 
1972
 
 
1973
 
%%%%%%%%%%%%%
1974
 
\subsection{End Elements}
1975
 
%%%%%%%%%%%%%
1976
 
 
1977
 
 
1978
 
 
1979
 
\<ScriptsManager: void endElement(ns, sName, qName)\><<<
1980
 
public void endElement(String ns, String sName, String qName){
1981
 
   String s = "</" + qName + ">";
1982
 
   if( savemode ){ code+=s; }
1983
 
   else { out.print(s); }
1984
 
   Object [] state = (Object []) stack.pop();     
1985
 
   if( (String) state[1] != null ){ 
1986
 
     `<invoke script`>
1987
 
     `<set end element`>
1988
 
     add( s );
1989
 
}  }
1990
 
>>>
1991
 
 
1992
 
 
1993
 
 
1994
 
 
1995
 
 
1996
 
 
1997
 
 
1998
 
\<invoke script\><<<
1999
 
Object parmValues[] = new Object[2]; 
2000
 
parmValues[0] = scripts.get( match );
2001
 
parmValues[1] = code; 
2002
 
try { 
2003
 
  s = (String) method.invoke( null, parmValues ); 
2004
 
} catch (Exception e){
2005
 
  System.err.println(
2006
 
         "--- ScriptsManager Error --- " + e );
2007
 
}
2008
 
>>>
2009
 
 
2010
 
 
2011
 
Can't invoke exception above.
2012
 
 
2013
 
\<set end element\><<<  
2014
 
savemode = ((Boolean) state[0]).booleanValue();
2015
 
code = (String) state[1]; 
2016
 
match = (String) state[2];
2017
 
>>>
2018
 
 
2019
 
 
2020
 
 
2021
 
 
2022
 
 
2023
 
 
2024
 
%%%%%%%%%%%%%%%%%%
2025
 
\subsection{Generic Lexical Handler}
2026
 
%%%%%%%%%%%%%%%%%%
2027
 
 
2028
 
\label{ScriptsManagerLH}
2029
 
 
2030
 
 
2031
 
The lexical handler sends its strings to the content hadler.
2032
 
 
2033
 
 
2034
 
 
2035
 
\AtEndDocument{
2036
 
   \OutputCodE\<ScriptsManagerLH.java\>
2037
 
}
2038
 
 
2039
 
\AddFile{ScriptsManagerLH.java}{xtpipes/lib}
2040
 
 
2041
 
 
2042
 
 
2043
 
\<ScriptsManagerLH.java\><<<
2044
 
// `version
2045
 
package xtpipes.lib;
2046
 
import org.xml.sax.ext.LexicalHandler;
2047
 
import org.xml.sax.ContentHandler;     
2048
 
public class ScriptsManagerLH implements LexicalHandler {
2049
 
       ScriptsManager contentHandler;
2050
 
   public ScriptsManagerLH( ScriptsManager contentHandler ){
2051
 
     this.contentHandler = contentHandler;
2052
 
   }
2053
 
   public void comment(char[] ch, int start, int length){
2054
 
     if( contentHandler.inBody ){
2055
 
        String s = new String(ch, start, length);
2056
 
        contentHandler.add(  "<!--" + s + "\n-->");
2057
 
   } }
2058
 
   public void startEntity(String x){}
2059
 
   public void endEntity(String x){}
2060
 
   public void startCDATA(){}
2061
 
   public void endCDATA(){}
2062
 
   public void startDTD(String x, String y, String z){}
2063
 
   public void endDTD(){} 
2064
 
}
2065
 
>>>
2066
 
 
2067
 
\begin{itemize}
2068
 
\item
2069
 
The line breaks in the comments are to avoid sequences of comments 
2070
 
loosing their intermediate line breaks and as a result causing 
2071
 
overflow of buffers.
2072
 
 
2073
 
\item The comments in the preamble are included through the 
2074
 
preamble pattribute of xtpipes.
2075
 
\end{itemize}
2076
 
 
2077
 
 
2078
 
 
2079
 
 
2080
 
%%%%%%%%%%%%%%%%%%
2081
 
\section{Unicode Filter}
2082
 
%%%%%%%%%%%%%%%%%%
2083
 
 
2084
 
Non ascii characters are translated into unicode hexadecimal entities.
2085
 
The same holds for ascii characters listed within the filter.
2086
 
 
2087
 
\AtEndDocument{
2088
 
   \OutputCodE\<XtpipesUni.java\>
2089
 
}
2090
 
\AddFile{XtpipesUni.java}{xtpipes}
2091
 
 
2092
 
 
2093
 
\<XtpipesUni.java\><<<
2094
 
// `version
2095
 
package xtpipes;
2096
 
public class XtpipesUni{
2097
 
   `<String toUni( char[], start, length, filter )`>
2098
 
   `<String toUni( String, filter )`>
2099
 
}
2100
 
>>>
2101
 
 
2102
 
\<String toUni( char[], start, length, filter )\><<<
2103
 
public static String toUni( char[] ch, int start, int length, 
2104
 
                                           String filter ){
2105
 
   StringBuffer buf = new StringBuffer(length);
2106
 
   for (int i = 0; i < length; i++) {
2107
 
       int chr = ch[ start + i ];
2108
 
       boolean ascii =  (chr == '\n')
2109
 
                        || (chr > 31) && (chr < 127) ;
2110
 
       if( filter.indexOf(chr) > -1 ){ ascii = false; }
2111
 
       buf.append(
2112
 
         ascii ? Character.toString((char) chr)
2113
 
               : ("&#x" 
2114
 
                 + Integer.toHexString(chr).toUpperCase()
2115
 
                 + ";" ) );
2116
 
   }
2117
 
   return new String(buf);
2118
 
}
2119
 
>>>
2120
 
 
2121
 
\<String toUni( String, filter )\><<<
2122
 
public static String toUni( String s, String filter ){
2123
 
   char [] ch = s.toCharArray();
2124
 
   int length = ch.length;
2125
 
   return toUni(ch, 0, length, filter);
2126
 
}
2127
 
>>>
2128
 
 
2129
 
 
2130
 
 
2131
 
 
2132
 
 
2133
2498
 
2134
2499
 
2135
2500
%%%%%%%%%%%%%%%%%%
2150
2515
 
2151
2516
\<class XtpipesEntityResolver\><<<
2152
2517
class XtpipesEntityResolver implements  org.xml.sax.EntityResolver { 
2153
 
      `<XtpipesEntityResolver fields`>
2154
 
   `<XtpipesEntityResolver()`>
2155
2518
   `<InputSource resolveEntity(publicID, systemId)`>
2156
 
   `<static String searchFile( file )`>
2157
 
   `<static String [] getPaths( dirs )`>
2158
 
   `<static String searchDirectory(dir, file)`>
2159
2519
}
2160
2520
>>>
2161
2521
 
 
2522
 
 
2523
%%%%%%%%%%%%%
 
2524
\subsection{Implementation}
 
2525
%%%%%%%%%%%%%
 
2526
 
 
2527
 
 
2528
 
2162
2529
\<InputSource resolveEntity(publicID, systemId)\><<<
2163
2530
public InputSource resolveEntity(String publicID, String systemID) 
2164
2531
                                                    throws SAXException {    
2165
2532
   if( Xtpipes.trace ){ 
2166
 
      Xtpipes.logWriter.println( "Resolving: PUBLIC \" " + publicID
2167
 
                + "\" \"" + systemID + "\"" ); 
 
2533
      Xtpipes.logWriter.println( "Resolving: publicID = \" " + publicID
 
2534
                + "\"  systemID = \"" + systemID + "\"" ); 
2168
2535
   } 
2169
 
   String file = searchFile( systemID );
2170
 
   if( file != null ){ return new InputSource( file ); }
 
2536
   String file = FileInfo.searchFile( systemID );
 
2537
   if( file != null ){ 
 
2538
     try{
 
2539
        file = new File(file).toURI().toURL().toString();
 
2540
        return new InputSource( file ); 
 
2541
     } catch( java.net.MalformedURLException mfe){
 
2542
        throw new SAXException(  
 
2543
          "--- xtpipes error 30 --- improper file name: " + file  );  
 
2544
   } }
2171
2545
   return null; 
2172
2546
}  
2173
2547
>>>
2174
2548
 
2175
2549
 
2176
2550
 
2177
 
\<XtpipesEntityResolver()\><<<
2178
 
XtpipesEntityResolver(){
2179
 
   if( classPaths == null ){
 
2551
%%%%%%%%%%%%%%%%%%
 
2552
\section{File Information}
 
2553
%%%%%%%%%%%%%%%%%%
 
2554
 
 
2555
 
 
2556
%%%%%%%%%%%%%
 
2557
\subsection{Outline}
 
2558
%%%%%%%%%%%%%
 
2559
 
 
2560
 
 
2561
 
 
2562
 
 
2563
 
 
2564
\AtEndDocument{
 
2565
   \OutputCodE\<FileInfo.java\>
 
2566
}
 
2567
 
 
2568
\AddFile{FileInfo.java}{xtpipes}
 
2569
 
 
2570
 
 
2571
 
 
2572
\<FileInfo.java\><<<
 
2573
package xtpipes;
 
2574
/*
 
2575
FileInfo.java (`version)
 
2576
*/
 
2577
`<FileInfo imports`>
 
2578
public class FileInfo{
 
2579
     `<FileInfo fields`>
 
2580
   public FileInfo(PrintWriter log, String iii_scriptDir, boolean trace){
 
2581
      FileInfo.log = log;
 
2582
      FileInfo.ii_scriptDir = iii_scriptDir;
 
2583
      FileInfo.trace = trace;
2180
2584
      `<classPaths[] := ...`>
2181
2585
      `<scriptPaths[] := ...`>
2182
 
}  }
2183
 
>>>
2184
 
 
 
2586
   }
 
2587
   `<static String searchFile( file )`>
 
2588
   `<static String [] getPaths( dirs )`>
 
2589
   `<static String cleanPath( path )`>
 
2590
   `<static String searchDirectory(dir, file)`>
 
2591
}
 
2592
>>>
 
2593
 
 
2594
\<FileInfo fields\><<<
 
2595
static String [] classPaths = null;
 
2596
static String [] scriptPaths = null;
 
2597
static java.util.HashMap <String,String> registry = 
 
2598
                                  new java.util.HashMap <String,String>();
 
2599
static String slash = System.getProperty("file.separator");
 
2600
static String ii_scriptDir;
 
2601
static PrintWriter log;
 
2602
static boolean trace;
 
2603
>>>
 
2604
 
 
2605
 
 
2606
\<FileInfo imports\><<<
 
2607
import java.io.File;
 
2608
import java.io.PrintWriter;
 
2609
>>>
2185
2610
 
2186
2611
%%%%%%%%%%%%%
2187
2612
\subsection{Search Engine}
2192
2617
 
2193
2618
\<static String searchFile( file )\><<<
2194
2619
public static String searchFile( String file ){
2195
 
   String key = Xtpipes.scriptDir + "!" + file;    
2196
 
   String result = (String) registery.get( key );
 
2620
   String key = ((ii_scriptDir == null)? "" : ii_scriptDir )
 
2621
                + "!" + file;   
 
2622
   String result = (String) registry.get( key );
2197
2623
   if( result == null ){
2198
2624
      for(int i=0; i<2; i++){
2199
 
         if( Xtpipes.trace ){ Xtpipes.logWriter.println( "Searching: " + file ); }
2200
 
         if( (new File(file)).exists() ){ result = file; }
 
2625
         if( trace ){ 
 
2626
            log.println( "Searching: " + file );
 
2627
         }
 
2628
         if( (new File(file)).exists() ){ 
 
2629
            result = ( file.indexOf(slash) == -1 )?
 
2630
                         (System.getProperty("user.dir") + slash + file)
 
2631
                        :
 
2632
                         file; 
 
2633
         }
2201
2634
         else {
2202
 
            if( Xtpipes.scriptDir != null ){
 
2635
            if( ii_scriptDir != null ){
2203
2636
               `<search file in script directories`> 
2204
2637
            }
2205
2638
            if( result == null ){ 
2208
2641
         if( result != null ){ break; }
2209
2642
         file =  new File(file).getName();
2210
2643
      }
2211
 
      if( result != null ){ registery.put(key, result); }  
 
2644
      if( result != null ){ 
 
2645
        result = FileInfo.cleanPath(result);
 
2646
        registry.put(key, result); 
 
2647
      }  
2212
2648
   }  
2213
 
   if( Xtpipes.trace ){ 
 
2649
   if( trace ){ 
2214
2650
      if( result == null ){
2215
 
         Xtpipes.logWriter.println( 
 
2651
         log.println( 
2216
2652
            "Directory paths from xtpipes command line option -i: "
2217
 
                                            + Xtpipes.scriptDir ); 
2218
 
      } else { Xtpipes.logWriter.println( "Found: " + result + "\n" ); }
2219
 
      Xtpipes.logWriter.flush();
 
2653
                                            + ii_scriptDir ); 
 
2654
      } else { log.println( "Found: " + result + "\n" ); }
 
2655
      log.flush();
2220
2656
   }
2221
2657
   return result; 
2222
2658
}  
2228
2664
int k = scriptPaths.length;  
2229
2665
while( k>0 ){  
2230
2666
  k--;  
2231
 
  if( Xtpipes.trace ){
2232
 
    Xtpipes.logWriter.println( "Searching: " + file 
 
2667
  if( trace ){
 
2668
    log.println( "Searching: " + file 
2233
2669
                   + ", recursively in directory: " + scriptPaths[k] ); 
2234
2670
  } 
2235
2671
  result = searchDirectory( new File(scriptPaths[k]), file);  
2236
2672
  if( result != null ){ break; }
2237
2673
}
2238
 
 
2239
 
String s = Xtpipes.scriptDir + file;
2240
 
 
 
2674
String s = ii_scriptDir + file;
2241
2675
if( (new File( s )).exists() ){ result = s; }
2242
2676
>>>
2243
2677
 
2248
2682
while( k>0 ){ 
2249
2683
  k--; 
2250
2684
  String s =  classPaths[k] + toFile;
2251
 
  if( Xtpipes.trace ){ Xtpipes.logWriter.println( "Searching: " + s ); }
 
2685
  if( trace ){ log.println( "Searching: " + s ); }
2252
2686
  if( new File(s).exists() ){ result = s; break; }
2253
2687
2254
2688
>>>
2280
2714
%%%%%%%%%%%%%
2281
2715
 
2282
2716
 
2283
 
\<XtpipesEntityResolver fields\><<<
2284
 
static String [] classPaths = null;
2285
 
static String [] scriptPaths = null;
2286
 
static String slash = System.getProperty("file.separator");
2287
 
static java.util.HashMap <String,String> registery = 
2288
 
                                  new java.util.HashMap <String,String>();
2289
 
>>>
2290
 
 
2291
 
\<classPaths[] := ...\><<<
2292
 
classPaths = getPaths( System.getProperty("java.class.path") );
2293
 
>>>
2294
 
 
2295
 
Script paths are to be encoded in a similar manner as calss paths.
2296
 
 
2297
 
\<classPaths[] := ...\><<<
2298
 
if( Xtpipes.scriptDir != null ){
2299
 
   scriptPaths = getPaths( Xtpipes.scriptDir );
 
2717
 
 
2718
 
 
2719
\<classPaths[] := ...\><<<
 
2720
classPaths = FileInfo.getPaths( System.getProperty("java.class.path") );
 
2721
>>>
 
2722
 
 
2723
Script paths are to be encoded in a similar manner as class paths.
 
2724
 
 
2725
\<classPaths[] := ...\><<<
 
2726
if( iii_scriptDir != null ){
 
2727
   scriptPaths = FileInfo.getPaths( iii_scriptDir );
2300
2728
}  
2301
2729
>>>
2302
2730
 
2319
2747
>>>
2320
2748
 
2321
2749
 
 
2750
 
2322
2751
\<set full path\><<<
 
2752
paths[k] = cleanPath( paths[k] );
 
2753
>>>
 
2754
 
 
2755
\<\><<<
2323
2756
if( (paths[k].length() > 0) && (paths[k].charAt(0) == '~') ){
2324
2757
  if( (paths[k].length() == 1)|| (paths[k].charAt(1) != '~') ){
2325
2758
    paths[k] = System.getProperty( "user.home" ) + paths[k].substring(1);
2330
2763
>>>
2331
2764
 
2332
2765
 
 
2766
%%%%%%%%%%%%%%%%%%
 
2767
\section{Input Objects for  XML Files}
 
2768
%%%%%%%%%%%%%%%%%%
 
2769
 
 
2770
The XML files my contain faults as a brute force approach is applied in
 
2771
which the file is scanned directly without trying to build an XML object.
 
2772
 
 
2773
%%%%%%%%%%%%%
 
2774
\subsection{Outline}
 
2775
%%%%%%%%%%%%%
 
2776
 
 
2777
 
 
2778
\AtEndDocument{
 
2779
   \OutputCodE\<InputObject.java\>
 
2780
}
 
2781
 
 
2782
\AddFile{InputObject.java}{xtpipes}
 
2783
 
 
2784
 
 
2785
\<InputObject.java\><<<
 
2786
package xtpipes;
 
2787
/*
 
2788
InputObject.java (`version)
 
2789
*/
 
2790
`<InputObject imports`>
 
2791
 
 
2792
public class InputObject{
 
2793
      `<InputObject fields`>
 
2794
   `<public InputObject(...)`>
 
2795
   `<java.io.InputStream getInputStream( filename )`>
 
2796
   `<java.io.InputStream getInputStream( url )`>
 
2797
   `<void buildProfile( boolean trace )`>
 
2798
   public InputStream getInputStream(){ return inputStream; }
 
2799
   public String getFilename(){
 
2800
      return (url == null)?
 
2801
         ( (connection == null)? filename 
 
2802
                               :
 
2803
                                 connection . getURL() . toString()
 
2804
         )
 
2805
       : url;
 
2806
   }
 
2807
   public String getContentType(){ return contentType; }
 
2808
   public String getMetaType(){ return metaType; }
 
2809
   public String getPublicId(){ return publicId; }
 
2810
   public String getSystemId(){ return systemId; }
 
2811
   public String getXtpipes(){ return xtpipes; }
 
2812
   public String getRoot(){ return root; }
 
2813
   public String getDtdRoot(){ return dtdRoot; }
 
2814
}
 
2815
>>>
 
2816
 
 
2817
\<InputObject fields\><<<
 
2818
InputStream inputStream = null;
 
2819
URLConnection connection = null;
 
2820
String filename = null;
 
2821
static PrintWriter log;
 
2822
>>>
 
2823
 
 
2824
\<InputObject imports\><<<
 
2825
import java.io.PrintWriter;
 
2826
import java.net.URL;
 
2827
import java.net.URLConnection;
 
2828
import java.io.ByteArrayInputStream;
 
2829
import java.io.File;
 
2830
import java.io.InputStream;
 
2831
>>>
 
2832
 
 
2833
%%%%%%%%%%%%%
 
2834
\subsection{Constructor}
 
2835
%%%%%%%%%%%%%
 
2836
 
 
2837
 
 
2838
 
 
2839
 
 
2840
\<public InputObject(...)\><<<
 
2841
public InputObject( String filename, PrintWriter log ){
 
2842
   InputObject.log = log;
 
2843
   filename = filename.trim(); 
 
2844
   try{ 
 
2845
      inputStream = getInputStream(filename); 
 
2846
   } catch (Exception exp0){ 
 
2847
      if( !filename.startsWith( "http://" ) ){ 
 
2848
         try{ 
 
2849
            String name = "http://" + filename;
 
2850
            inputStream = getInputStream( name ); 
 
2851
            filename = name; 
 
2852
         } catch (Exception exp1){ 
 
2853
            try{  
 
2854
               String name = FileInfo.cleanPath(filename);
 
2855
               inputStream = getInputStream( name ); 
 
2856
               filename = name; 
 
2857
            } catch (Exception exp2){ inputStream = null; } 
 
2858
   }  }  }  
 
2859
   this.filename = filename;
 
2860
}
 
2861
>>>
 
2862
 
 
2863
\<public InputObject(...)\><<<
 
2864
public InputObject( byte [] bytes, PrintWriter log ){
 
2865
   InputObject.log = log;
 
2866
   inputStream = new ByteArrayInputStream( bytes );
 
2867
}
 
2868
>>>
 
2869
 
 
2870
 
 
2871
 
 
2872
%%%%%%%%%%%%%
 
2873
\subsection{Stream from a  File Name}
 
2874
%%%%%%%%%%%%%
 
2875
 
 
2876
 
 
2877
 
 
2878
\<java.io.InputStream getInputStream( filename )\><<<
 
2879
private java.io.InputStream getInputStream(
 
2880
                                      String filename )
 
2881
                                   throws java.io.IOException{
 
2882
   if( filename == null ){ return null; }
 
2883
   URL url;
 
2884
   java.io.InputStream inputStream = null;
 
2885
//   String loadingError = "Failed to get requested file.";
 
2886
   try {
 
2887
      url = new File(filename).toURI().toURL();
 
2888
      inputStream =  getInputStream( url );
 
2889
   } catch (Exception ie) {
 
2890
       try {
 
2891
           url = new URL(filename);
 
2892
           inputStream =  getInputStream( url );
 
2893
       } catch (java.io.FileNotFoundException ife) {
 
2894
           throw new java.io.IOException(
 
2895
              "File not found: " + filename);
 
2896
       } catch (Exception ife) {
 
2897
           throw new java.io.IOException(ife + "\n" + ie);
 
2898
   }   }
 
2899
   return inputStream;
 
2900
}
 
2901
>>>
 
2902
 
 
2903
 
 
2904
%%%%%%%%%%%%%
 
2905
\subsection{Stream from a URL}
 
2906
%%%%%%%%%%%%%
 
2907
 
 
2908
\<java.io.InputStream getInputStream( url )\><<<   
 
2909
private java.io.InputStream getInputStream( URL url )
 
2910
                            throws java.io.FileNotFoundException,
 
2911
                                             java.io.IOException {
 
2912
   java.io.InputStream inputStream = null;
 
2913
   String errMssg = "";
 
2914
   try{
 
2915
      connection = null;
 
2916
      connection = url.openConnection();
 
2917
      connection.setRequestProperty("User-Agent",
 
2918
                      "["
 
2919
                    + System.getProperty("os.name")
 
2920
                    + " / "
 
2921
                    + System.getProperty("os.arch")
 
2922
                    + "]"
 
2923
                    + "["
 
2924
                    + System.getProperty("java.version")
 
2925
                    + " - "
 
2926
                    + System.getProperty("java.vendor")
 
2927
                    + "]"
 
2928
 
 
2929
           );
 
2930
      inputStream = connection.getInputStream();
 
2931
   } catch(java.io.FileNotFoundException ve){
 
2932
      errMssg = "File not found: " + url;
 
2933
      throw new java.io.FileNotFoundException(
 
2934
                 "--- Ml2xml input error --- " + errMssg );
 
2935
   } catch (javax.net.ssl.SSLHandshakeException ve){
 
2936
      errMssg = "SSL Handshake Exception: " + ve.getMessage();
 
2937
      throw new javax.net.ssl.SSLHandshakeException(
 
2938
                 "--- Ml2xml input error --- " + errMssg );
 
2939
   } catch (java.net.UnknownHostException ve){
 
2940
      errMssg = "Unknown Host Exception: " + ve.getMessage();
 
2941
      throw new java.net.UnknownHostException(
 
2942
                   "--- Ml2xml input error --- " + errMssg );
 
2943
   }
 
2944
   return inputStream;
 
2945
}
 
2946
>>>
 
2947
 
 
2948
 
 
2949
 
 
2950
%%%%%%%%%%%%%
 
2951
\subsection{Clean Path}
 
2952
%%%%%%%%%%%%%
 
2953
 
 
2954
 
 
2955
 
 
2956
\<static String cleanPath( path )\><<< 
 
2957
public static String cleanPath( String path ){ 
 
2958
     String slash = System.getProperty("file.separator");
 
2959
     String userDir = System.getProperty( "user.dir" );
 
2960
  `<clean leading wigle`>
 
2961
  `<clean leading dots`>
 
2962
  `<clean internal dots`>
 
2963
  return path; 
 
2964
 
2965
>>> 
 
2966
 
 
2967
\<clean leading wigle\><<< 
 
2968
  if( (path.length() > 0) && (path.charAt(0) == '~') ){  
 
2969
    if( (path.length() == 1) || (path.charAt(1) != '~') ){  
 
2970
      path = System.getProperty( "user.home" ) 
 
2971
                             + path.substring(1);  
 
2972
  } } 
 
2973
>>>
 
2974
 
 
2975
\<clean leading dots\><<<
 
2976
  if( path.startsWith("..") ){  
 
2977
     path = userDir.substring(0, 
 
2978
               Math.max(0,Math.max( 
 
2979
                 userDir.lastIndexOf("/") 
 
2980
                 , 
 
2981
                 userDir.lastIndexOf("\\") 
 
2982
               ))) 
 
2983
            + path.substring(2);  
 
2984
  }  
 
2985
  if( path.startsWith(".") ){  
 
2986
     path = userDir + slash + path.substring(1);  
 
2987
  }  
 
2988
>>>
 
2989
 
 
2990
\<clean internal dots\><<<
 
2991
  int i; 
 
2992
  while(  
 
2993
    ((i=path.indexOf("/..")) != -1)  
 
2994
    || 
 
2995
    ((i=path.indexOf("\\..")) != -1)  
 
2996
  ){ 
 
2997
    String s = path.substring(0,i); 
 
2998
    int j = Math.max(s.lastIndexOf("/"), s.lastIndexOf("\\")); 
 
2999
    path = path.substring(0,j) + path.substring(i+3); 
 
3000
  } 
 
3001
  while(  
 
3002
    ((i=path.indexOf("/.")) != -1)  
 
3003
    || 
 
3004
    ((i=path.indexOf("\\.")) != -1)  
 
3005
  ){ 
 
3006
    String s = path.substring(0,i); 
 
3007
    int j = Math.max(s.indexOf("/"), s.indexOf("\\")); 
 
3008
    path = path.substring(0,j) + path.substring(i+2); 
 
3009
  } 
 
3010
>>>
 
3011
 
 
3012
 
 
3013
 
 
3014
%%%%%%%%%%%%%
 
3015
\subsection{Profile: Connecting and Reading the Input File}
 
3016
%%%%%%%%%%%%%
 
3017
 
 
3018
\<void buildProfile( boolean trace )\><<<
 
3019
public void buildProfile( boolean trace ){
 
3020
   if( trace ){
 
3021
      log.println(
 
3022
         "xtpipes (`version)"
 
3023
         + "\n   java.version: "    + System.getProperty("java.version")  
 
3024
         + "\n   java.class.path: " + System.getProperty("java.class.path")  
 
3025
         + "\n   os.name: "         + System.getProperty("os.name")  
 
3026
         + "\n   user.home: "       + System.getProperty("user.home")  
 
3027
         + "\n   user.dir: "        + System.getProperty("user.dir")  
 
3028
           );
 
3029
   }
 
3030
   if( connection != null ){ 
 
3031
     `<profile info from connection`>
 
3032
   }
 
3033
   `<profile from preamble of file`>
 
3034
   if( trace ){
 
3035
      log.println(
 
3036
           " url = "           + url 
 
3037
         + "\n contentType = " + contentType
 
3038
         + "\n publicId = "    + publicId 
 
3039
         + "\n systemId = "    + systemId
 
3040
         + "\n xtpipes = "     + xtpipes
 
3041
         + "\n root = "        + root
 
3042
         + "\n dtdRoot = "     + dtdRoot
 
3043
      ); 
 
3044
}  }
 
3045
>>>
 
3046
 
 
3047
 
 
3048
\<profile info from connection\><<< 
 
3049
contentType = connection . getContentType(); 
 
3050
url = connection . getURL() . toString();
 
3051
>>> 
 
3052
 
 
3053
 
 
3054
 
 
3055
\<profile from preamble of file\><<< 
 
3056
int max = 8192; 
 
3057
int buffSize = 4096;
 
3058
byte [] buff = new byte [ buffSize ];
 
3059
int m = 0; 
 
3060
int length = 0; 
 
3061
int ch;
 
3062
int type = `<undef type`>;
 
3063
String token = null;
 
3064
while( m < max ){ 
 
3065
   try{ 
 
3066
      int k = Math.min( max - m, buffSize ); 
 
3067
      length = inputStream.read( buff, 0, k ); 
 
3068
      if( length == -1 ){ break; } 
 
3069
      if( length == 0  ){ continue; }  
 
3070
   } catch (java.io.IOException e){ 
 
3071
      System.err.println( "--- xtpipes error --- : " + e );  
 
3072
      break; 
 
3073
   } 
 
3074
   for(int i = 0 ; i < length; i++ ){ 
 
3075
     `<search preamble info`> 
 
3076
     m++; 
 
3077
}  } 
 
3078
>>> 
 
3079
 
 
3080
 
 
3081
%%%%%%%%%%%%%
 
3082
\subsection{Profile: Scanning the Different Cases}
 
3083
%%%%%%%%%%%%%
 
3084
 
 
3085
 
 
3086
 
 
3087
 
 
3088
\<search preamble info\><<< 
 
3089
switch( ch = buff[i] ){ 
 
3090
   case  '<':  token = ""; 
 
3091
               type = `<new tok`>;
 
3092
               break; 
 
3093
   case  '>':  if( token != null ){
 
3094
                  token = token . replaceAll( "\\s+", " ");
 
3095
                  `<at token end`>
 
3096
                  token = null;
 
3097
               }
 
3098
               break; 
 
3099
   case '\n':  
 
3100
   case  ' ':  if( token != null ){ 
 
3101
                  `<at token space`>
 
3102
               }
 
3103
               break; 
 
3104
   case  '"':
 
3105
   case '\'':  if( token == null ){ break; }
 
3106
               `<public and system ids`>
 
3107
   default:    if( token != null ){                   
 
3108
                  if( type == `<pre doctype`> ){
 
3109
                     if( ch == 'D' ){
 
3110
                        type = `<doctype`>;
 
3111
                        token += (char) ch;
 
3112
                     } else { token = null; type = `<undef type`>; }
 
3113
                  } 
 
3114
                  else 
 
3115
                  if( token.equals("") && (type == `<new tok`>) ){
 
3116
                     `<get token type`>
 
3117
                  } else { token += (char) ch; }
 
3118
}              } 
 
3119
>>> 
 
3120
 
 
3121
 
 
3122
\<public and system ids\><<<
 
3123
if( !token.trim().equals("") ){
 
3124
   if( token.trim().charAt(0) == ch ){
 
3125
     if( type == `<public id`> ){
 
3126
        publicId = token.trim().substring(1);
 
3127
        type = `<system id`>;
 
3128
        token = "";
 
3129
        break;
 
3130
     } 
 
3131
     else if( type == `<system id`> ){
 
3132
        systemId = token.trim().substring(1);
 
3133
        token = null;
 
3134
        break;
 
3135
     }
 
3136
} }
 
3137
>>>
 
3138
 
 
3139
 
 
3140
\<get token type\><<<
 
3141
switch( ch ){
 
3142
   case '!': type = `<pre doctype`>;
 
3143
             break;
 
3144
   case '?': type = `<proc instruction`> ;
 
3145
             break;
 
3146
   default:  if( Character.isLetter(ch) 
 
3147
                 && ((root == null) || (metaType == null)) ){ 
 
3148
                type = `<root or meta`>;
 
3149
                token += (char) ch; 
 
3150
             } else { token = null; }
 
3151
}
 
3152
>>>
 
3153
 
 
3154
\<at token end\><<<
 
3155
if( type == `<proc instruction`> ){
 
3156
   if( xtpipes == null ){
 
3157
      int n = token.length();
 
3158
      if( (n > 1) && (token.charAt( n - 1 ) == '?')
 
3159
                  && (token.startsWith("xtpipes") ) ){
 
3160
         String s = token . substring(7,n-1) . replaceAll( "\\s+", "");
 
3161
         n = s.length();
 
3162
         if( (n>6) && (s.startsWith("file="))
 
3163
                   && (s.charAt(5) == s.charAt(n-1)) ){
 
3164
           xtpipes = s.substring(6,n-1);
 
3165
   }  }  }
 
3166
} else if( type == `<meta`> ){
 
3167
   if( metaType == null ){
 
3168
      token = token . replaceAll( "\\s+", "");
 
3169
      int k = token.indexOf("http-equiv");
 
3170
      int n = token.indexOf("content");
 
3171
      if( (k != -1) && (n != -1) ){
 
3172
         if( token.length() > (Math.max(k,n)+3) ){
 
3173
            if( token.substring(k+12).startsWith("Content-Type") ){
 
3174
               token = token.substring(n+9);
 
3175
               n = token.indexOf(";");
 
3176
               if( n !=-1 ){ metaType = token.substring(0,n); }
 
3177
   }  }  }  }
 
3178
} else if( (type == `<root or meta`>) && (root == null) ){
 
3179
   root = token;
 
3180
}
 
3181
>>>
 
3182
 
 
3183
\<at token space\><<<
 
3184
if( type == `<root or meta`> ){
 
3185
   if( token.equals("meta") ){
 
3186
      if( metaType == null ){
 
3187
         type = `<meta`>;
 
3188
         token = " ";
 
3189
      } else {
 
3190
         token = null;
 
3191
      }
 
3192
   } else { 
 
3193
      if( root == null ){
 
3194
        root = token;
 
3195
      }
 
3196
      token = null;
 
3197
   }
 
3198
} else if( type == `<doctype`> ){
 
3199
   if( token.equals("DOCTYPE") ){
 
3200
      type = `<doctype root`>;
 
3201
      token = " ";
 
3202
   } else { token = null; }
 
3203
} else if( type == `<doctype root`> ){   
 
3204
   if( !token.trim().equals("") ){
 
3205
      dtdRoot = token.trim();
 
3206
      token = " ";
 
3207
      type = `<doctype id`>;
 
3208
   } else { token = null; }
 
3209
} else if( type == `<doctype id`> ){
 
3210
   if( !token.trim().equals("") ){
 
3211
      token = token.trim();
 
3212
      if( token.equals("PUBLIC") ){
 
3213
         type = `<public id`>;
 
3214
         token = "";
 
3215
      } else if( token.equals("SYSTEM") ){
 
3216
         type = `<system id`>;
 
3217
         token = "";
 
3218
      } else { token = null; }
 
3219
   }
 
3220
} else { token += ' '; }
 
3221
>>>
 
3222
 
 
3223
 
 
3224
\<InputObject fields\><<<
 
3225
String dtdRoot = null,
 
3226
      publicId = null,
 
3227
      systemId = null,
 
3228
       xtpipes = null,
 
3229
           url = null,
 
3230
      metaType = null,
 
3231
   contentType = null,
 
3232
          root = null;
 
3233
>>>
 
3234
 
 
3235
\OP{undef type}
 
3236
\OP{new tok}
 
3237
\OP{root or meta}
 
3238
\OP{pre doctype}
 
3239
\OP{doctype}
 
3240
\OP{doctype root}
 
3241
\OP{doctype id}
 
3242
\OP{public id}
 
3243
\OP{system id}
 
3244
\OP{proc instruction}
 
3245
\OP{proc root}
 
3246
\OP{meta}
 
3247
 
 
3248
 
 
3249
%%%%%%%%%%%%%%%%%%
 
3250
\section{Input Objects for XML Strings}
 
3251
%%%%%%%%%%%%%%%%%%
 
3252
 
 
3253
 
 
3254
 
 
3255
%%%%%%%%%%%%%
 
3256
\subsection{Search String for Indirection}
 
3257
%%%%%%%%%%%%%
 
3258
 
 
3259
 
 
3260
\<search string for xtpipes instruction\><<<
 
3261
scriptFile = inputObject.getXtpipes();
 
3262
rootName = inputObject.getRoot();
 
3263
needScript = true;
 
3264
>>>
 
3265
 
 
3266
 
 
3267
Remove XtPipesSearch!!!!!!!!!!!!!!
 
3268
 
 
3269
\<\><<<
 
3270
try{ 
 
3271
       `<get sax reader`>      
 
3272
       saxReader.setContentHandler( new XtPipesSearch() );
 
3273
      `<body of search string for xtpipes instruction`>
 
3274
       saxReaderStack.push( saxReader );   
 
3275
} catch(Exception e){   
 
3276
e.printStackTrace();
 
3277
   instructionErr( node, errMsg + e.toString(), 13 );   
 
3278
}
 
3279
>>>
 
3280
 
 
3281
\<body of search string for xtpipes instruction\><<<
 
3282
errMsg = "Searching <?xtpipes file=\"...\"?>  in "
 
3283
        + inData.substring(0, Math.min(70,inData.length()))
 
3284
        + "... : ";
 
3285
byte [] bytes = inData.getBytes("UTF-8");
 
3286
ByteArrayInputStream bais = new ByteArrayInputStream( bytes );
 
3287
InputSource is = new InputSource( bais );
 
3288
saxReader.parse(is);
 
3289
>>>
 
3290
 
 
3291
%%%%%%%%%%%%%
 
3292
\subsection{The Search Engine}
 
3293
%%%%%%%%%%%%%
 
3294
 
 
3295
 
 
3296
 
 
3297
\<xtpipes fields DELETED\><<<
 
3298
private static class XtPipesSearch extends DefaultHandler {
 
3299
   public void  endElement(String uri, 
 
3300
                           String localName, String qName){
 
3301
     `<extract root element name`>
 
3302
   }
 
3303
   public void processingInstruction(String target, String attrs) {
 
3304
     if( !needScript && target.equals("xtpipes") ){
 
3305
        `<extract script file name`>
 
3306
}  } }
 
3307
>>>
 
3308
 
 
3309
 
 
3310
The input file is
 
3311
searched for an alternative script within a processing instruction of
 
3312
the form \verb+<?xtpipes file="..." ?>+.
 
3313
 
 
3314
 
 
3315
\<extract root element name\><<<
 
3316
rootName = qName;
 
3317
>>>
 
3318
 
 
3319
 
 
3320
\<extract script file name\><<<
 
3321
try {
 
3322
   `<get sax reader`>      
 
3323
   saxReader.setContentHandler(new DefaultHandler() { 
 
3324
      public void startElement(String uri, String localName, 
 
3325
         String qName, Attributes atts) { 
 
3326
         String filename = atts.getValue("file");
 
3327
         if( filename != null ){
 
3328
            scriptFile = filename;
 
3329
            `<show script file name in log file`>
 
3330
            needScript = true;
 
3331
      }  }
 
3332
   }); 
 
3333
   String str = "<xtpipes " + attrs + "/>"; 
 
3334
   StringReader reader = new StringReader(str); 
 
3335
   InputSource in = new InputSource(reader); 
 
3336
   saxReader.parse(in); 
 
3337
   saxReaderStack.push( saxReader );
 
3338
} catch(Exception e){ 
 
3339
   System.err.println( "--- Error 10 --- " + e ); 
 
3340
 
3341
>>>
 
3342
 
 
3343
 
 
3344
 
 
3345
 
 
3346
 
 
3347
 
 
3348
 
 
3349
\<xtpipes fields\><<<
 
3350
private static String  rootName;
 
3351
>>>
 
3352
 
 
3353
 
 
3354
\<init fields\><<<
 
3355
rootName = null;
 
3356
>>>
 
3357
 
 
3358
 
 
3359
 
 
3360
 
 
3361
%%%%%%%%%%%%%%%%%%
 
3362
\section{Information About the Transformation}
 
3363
%%%%%%%%%%%%%%%%%%
 
3364
 
 
3365
%%%%%%%%%%%%%
 
3366
\subsection{User's System}
 
3367
%%%%%%%%%%%%%
 
3368
 
 
3369
 
 
3370
 
 
3371
\<output system info\><<<
 
3372
logWriter.println(
 
3373
     "xtpipes (`version)"
 
3374
     + "\n java.version: "    + System.getProperty("java.version")  
 
3375
     + "\n java.class.path: " + System.getProperty("java.class.path")  
 
3376
     + "\n os.name: "         + System.getProperty("os.name")  
 
3377
     + "\n user.home: "       + System.getProperty("user.home")  
 
3378
     + "\n user.dir: "        + System.getProperty("user.dir") 
 
3379
);
 
3380
for( int k=0; k<args.length; k++ ){
 
3381
  logWriter.println( "     " + args[k] );
 
3382
}
 
3383
>>>
 
3384
    
 
3385
%%%%%%%%%%%%%
 
3386
\subsection{Script to be Used}
 
3387
%%%%%%%%%%%%%
 
3388
 
 
3389
 
 
3390
\<show script file name in log file\><<<
 
3391
if( messages ){
 
3392
   logWriter.println(
 
3393
      "Requesting XtPipes script file: "
 
3394
      + filename );
 
3395
}
 
3396
>>>
 
3397
 
 
3398
 
 
3399
%%%%%%%%%%%%%
 
3400
\subsection{Preamble Attribute}
 
3401
%%%%%%%%%%%%%
 
3402
 
 
3403
\<preamble output into log\><<<
 
3404
if ( (attr != null) && messages ) {
 
3405
   logWriter.println( attr.getNodeValue() );
 
3406
}
 
3407
>>>
 
3408
 
 
3409
 
 
3410
 
 
3411
%%%%%%%%%%%%%
 
3412
\subsection{Tracing}
 
3413
%%%%%%%%%%%%%
 
3414
 
 
3415
 
 
3416
\<xtpipes fields\><<<
 
3417
static boolean trace;
 
3418
>>>
 
3419
 
 
3420
\<init fields\><<<
 
3421
trace = false;
 
3422
>>>
 
3423
 
 
3424
 
 
3425
 
 
3426
\<trace element\><<<
 
3427
if( trace ){
 
3428
   logWriter.print( "[##] = xtpipes => " + instruction );
 
3429
   if( node.hasAttributes() ){
 
3430
      NamedNodeMap attributes = node.getAttributes();
 
3431
      for(int i=0; i < attributes.getLength(); i++ ){
 
3432
         Node attr = attributes.item(i);
 
3433
         logWriter.print( " "   + attr.getNodeName() 
 
3434
                         + "=\"" + attr.getNodeValue() + "\"" );
 
3435
   } } 
 
3436
   logWriter.println(); logWriter.flush();
 
3437
}
 
3438
>>>
 
3439
 
 
3440
\<trace if true\><<<
 
3441
if( trace ){
 
3442
   logWriter.print( "--> true" );
 
3443
}
 
3444
>>>
 
3445
 
 
3446
\<trace if false\><<<
 
3447
if( trace ){
 
3448
   logWriter.print( "--> true" );
 
3449
}
 
3450
>>>
 
3451
 
 
3452
 
 
3453
\<trace open script\><<<
 
3454
if( trace ){
 
3455
   logWriter.println( "(" + scriptFile + ")" );
 
3456
}
 
3457
>>>
 
3458
 
2333
3459
 
2334
3460
 
2335
3461
%%%%%%%%%%%%%%%%%%
2336
3462
\section{loose Ends}
2337
3463
%%%%%%%%%%%%%%%%%%
2338
3464
 
2339
 
 
2340
 
%%%%%%%%%%%%%
2341
 
\subsection{Error Messages}
2342
 
%%%%%%%%%%%%%
2343
 
 
2344
 
 
2345
 
 
2346
 
 
2347
 
 
2348
 
 
2349
 
\<static void instructionErr( node, e, num )\><<<
2350
 
static void instructionErr( Node node, String e, int num )
 
3465
%%%%%%%%%%%%%%%%%%
 
3466
\subsection{Fix XML Defaults}
 
3467
%%%%%%%%%%%%%%%%%%
 
3468
 
 
3469
\<xtpipes fields\><<<
 
3470
private static String [] ml2xml = null;
 
3471
static Class<?> ml2xmlClassObj = null;
 
3472
>>>
 
3473
 
 
3474
\<scan ml2xml argument\><<<
 
3475
if( args[n].substring(2).equals("") ){
 
3476
   if( ml2xml == null ){ ml2xml = new String[0]; }
 
3477
} else {
 
3478
   if( ml2xml == null ){
 
3479
      ml2xml = new String[1];
 
3480
   } else {
 
3481
      String [] m2x = new String [ml2xml.length + 1];
 
3482
      for(int cnt=0; cnt < ml2xml.length; cnt++){
 
3483
        m2x[cnt] = ml2xml[cnt];
 
3484
      }  
 
3485
      ml2xml = m2x;
 
3486
   }
 
3487
   ml2xml[ ml2xml.length - 1 ] = args[n].substring(2);
 
3488
}
 
3489
>>>
 
3490
 
 
3491
 
 
3492
\<inputStream := (InputStream) new Ml2xml(filename, "foo.m2x")\><<<
 
3493
try{
 
3494
   ml2xmlClassObj = Class.forName( "ml2xml.Ml2xml" );
 
3495
} catch (java.lang.ClassNotFoundException cnf ){
 
3496
   instructionErr( null, "Class not found: ml2xml.Ml2xml", 25 ); 
 
3497
}
 
3498
Class<?> [] argTyp = { String.class, String[].class }; 
 
3499
Constructor<?> con = ml2xmlClassObj.getConstructor( argTyp ); 
 
3500
try{
 
3501
   `<trace call to ml2xml`>
 
3502
   inputStream = (InputStream) con.newInstance( 
 
3503
         new Object[]{xml, ml2xml}
 
3504
      ); 
 
3505
} catch(java.lang.reflect.InvocationTargetException ite){
 
3506
   String s = "Problem at: ml2xml.Ml2xml(" + xml + ","
 
3507
              + "new String[]{" ;
 
3508
   for(int i=0; i < Xtpipes.ml2xml.length; i++){
 
3509
      s += ((i==0)? "\"" : ", \"") + Xtpipes.ml2xml[i] + "\"";
 
3510
   }
 
3511
   s += "})";          
 
3512
   instructionErr( null, s + "; " + ite.getCause(), 38); 
 
3513
}
 
3514
>>>
 
3515
 
 
3516
 ite.getTargetException().printStackTrace();
 
3517
 
 
3518
 
 
3519
\<Ml2xml close files\><<<
 
3520
if( Xtpipes.ml2xml != null ){
 
3521
   Class<?> [] argTyp = {}; 
 
3522
   Method m = ml2xmlClassObj . getMethod( "closeFiles", argTyp ); 
 
3523
   m.invoke( null, new Object[0] ); 
 
3524
}  
 
3525
>>>
 
3526
 
 
3527
\<trace call to ml2xml\><<<
 
3528
if( Xtpipes.trace ){
 
3529
   String s = "Calling: ml2xml.Ml2xml(inputStream,"
 
3530
              + "new String[]{" ;
 
3531
   for(int i=0; i < Xtpipes.ml2xml.length; i++){
 
3532
      s += ((i==0)? "\"" : ", \"") + Xtpipes.ml2xml[i] + "\"";
 
3533
   }
 
3534
   s += "})";          
 
3535
   Xtpipes.logWriter.println( s );      
 
3536
}
 
3537
>>>
 
3538
 
 
3539
 
 
3540
\<close ml2xml files\><<<
 
3541
if( ml2xmlClassObj != null ){
 
3542
  Class<?> [] argTypes = { }; 
 
3543
  Method m = ml2xmlClassObj.getMethod( "closeFiles", argTypes ); 
 
3544
  Object parmValues[] = new Object[0]; 
 
3545
  m.invoke( null, parmValues ); 
 
3546
}
 
3547
>>>
 
3548
 
 
3549
 
 
3550
\<xtpipes imports\><<<
 
3551
import java.lang.reflect.Constructor;
 
3552
>>>
 
3553
 
 
3554
Ml2xml is referenced through reflection instead of directly so that xtpipes can
 
3555
be delivered also without that utility, e.g., for tex4ht where no treatment of faulty 
 
3556
XML file is to be done. In fact, this approach can be generalized to offer 
 
3557
arbitrary filter for the input.
 
3558
 
 
3559
 
 
3560
 
 
3561
 
 
3562
%%%%%%%%%%%%%%%%%%
 
3563
\subsection{Unicode Filter}
 
3564
%%%%%%%%%%%%%%%%%%
 
3565
 
 
3566
Non ascii characters are translated into unicode hexadecimal entities.
 
3567
The same holds for ascii characters listed within the filter.
 
3568
 
 
3569
\AtEndDocument{
 
3570
   \OutputCodE\<XtpipesUni.java\>
 
3571
}
 
3572
\AddFile{XtpipesUni.java}{xtpipes}
 
3573
 
 
3574
 
 
3575
\<XtpipesUni.java\><<<
 
3576
// `version
 
3577
package xtpipes;
 
3578
public class XtpipesUni{
 
3579
   `<String toUni( char[], start, length, filter )`>
 
3580
   `<String toUni( String, filter )`>
 
3581
}
 
3582
>>>
 
3583
 
 
3584
\<String toUni( char[], start, length, filter )\><<<
 
3585
private static int D800 = Integer.parseInt("D800", 16); 
 
3586
private static int DFFF = Integer.parseInt("DFFF", 16);  
 
3587
private static int DC00 = Integer.parseInt("DC00", 16); 
 
3588
private static int X400 = Integer.parseInt("400",16); 
 
3589
private static int X10000 = Integer.parseInt("10000",16);
 
3590
 
 
3591
 
 
3592
public static String toUni( char[] ch, int start, int length, 
 
3593
                                           String filter ){
 
3594
   StringBuffer buf = new StringBuffer(length);
 
3595
   for (int i = 0; i < length; i++) {
 
3596
       int chr = ch[ start + i ];
 
3597
       boolean ascii =  (chr == '\n')
 
3598
                        || (chr > 31) && (chr < 127) ;
 
3599
       if( filter.indexOf(chr) > -1 ){ ascii = false; }
 
3600
 
 
3601
       if( (chr >= D800) && (chr<= DFFF) ){ 
 
3602
          chr = ((ch[i] - D800) * X400 + (ch[++i] - DC00)) + X10000;       
 
3603
       } 
 
3604
 
 
3605
 
 
3606
       buf.append(
 
3607
         ascii ? Character.toString((char) chr)
 
3608
               : ("&#x" 
 
3609
                 + Integer.toHexString(chr).toUpperCase()
 
3610
                 + ";" ) );
 
3611
   }
 
3612
   return new String(buf);
 
3613
}
 
3614
>>>
 
3615
 
 
3616
\<String toUni( String, filter )\><<<
 
3617
public static String toUni( String s, String filter ){
 
3618
   char [] ch = s.toCharArray();
 
3619
   int length = ch.length;
 
3620
   return toUni(ch, 0, length, filter);
 
3621
}
 
3622
>>>
 
3623
 
 
3624
 
 
3625
 
 
3626
 
 
3627
 
 
3628
 
 
3629
 
 
3630
%%%%%%%%%%%%%
 
3631
\subsection{Error Messagesg}
 
3632
%%%%%%%%%%%%%
 
3633
 
 
3634
 
 
3635
 
 
3636
 
 
3637
 
 
3638
 
 
3639
\<static void instructionErr(...)\><<<
 
3640
private static void instructionErr( Node node, String e, int num )
2351
3641
                                     throws Exception {
2352
3642
   String err = "--- xtpipes error " + num + " --- ";
2353
3643
   if( node != null ){
2362
3652
      err += " > : " ; 
2363
3653
   }
2364
3654
   err += e;
 
3655
   `<close ml2xml files`>
2365
3656
   Xtpipes.logWriter.flush();
2366
 
   if( exceptionErrs ) {  throw new Exception( err );  }   
 
3657
   if( exceptionErrs ) { throw new Exception( err );  }   
2367
3658
   else { 
2368
3659
      System.err.println( err );
2369
3660
      System.exit(1); 
2373
3664
 
2374
3665
 
2375
3666
 
 
3667
\<static void instructionErr(...)\><<<
 
3668
private static void instructionErr( Node node, String e,
 
3669
                                StackTraceElement[] st, int num )
 
3670
                                     throws Exception {
 
3671
   Xtpipes.logWriter.println(
 
3672
      "--- xtpipes error " + num + " --- " + e
 
3673
   );
 
3674
   for(int i=st.length-1; i>=0; i-- ){ 
 
3675
      Xtpipes.logWriter.println( st[i].toString() ); 
 
3676
   } 
 
3677
   instructionErr( node, e, num );
 
3678
}
 
3679
>>>
 
3680
 
 
3681
 
 
3682
 
2376
3683
 
2377
3684
\<new ErrorHandler()\><<<
2378
3685
new ErrorHandler() {
2387
3694
    }
2388
3695
    public void showSpecifics(String s, SAXParseException e)
2389
3696
                                                throws SAXParseException {
2390
 
      String err =   "--- xtpipes " + s + " 23 --- " + e.getSystemId()
 
3697
      String err =   "--- xtpipes " + s + " 24 --- " + e.getSystemId()
2391
3698
                     + " line " + e.getLineNumber()
2392
3699
                     + " col "  + e.getColumnNumber()
2393
3700
                     + " : "    + e.getMessage() ;
2402
3709
 
2403
3710
 
2404
3711
 
2405
 
\<transformer error listener\><<<
2406
 
new ErrorListener() {
2407
 
   public void warning(TransformerException e) throws TransformerException {
2408
 
     showSpecifics(".....warning", e);
2409
 
   }
2410
 
   public void error(TransformerException e) throws TransformerException {
2411
 
     showSpecifics(".....error", e);
2412
 
   }
2413
 
   public void fatalError(TransformerException e) throws TransformerException {
2414
 
     showSpecifics("fatal .....error", e);
2415
 
   }          
2416
 
   void showSpecifics(String s, TransformerException e)
2417
 
                                               throws  TransformerException{
2418
 
     String err = e.getMessage() ;
2419
 
     String loc = e.getLocationAsString();
2420
 
     if( loc != null ){ err = loc + ": " + err; }
2421
 
     throw new TransformerException(err);
2422
 
}  }
2423
 
>>>
2424
 
 
2425
 
 
2426
 
 
2427
 
%%%%%%%%%%%%%
2428
 
\subsection{Tracing}
2429
 
%%%%%%%%%%%%%
2430
 
 
2431
 
 
2432
 
\<xtpipes members\><<<
2433
 
static boolean trace;
2434
 
>>>
2435
 
 
2436
 
\<init fields\><<<
2437
 
trace = false;
2438
 
>>>
2439
 
 
2440
 
 
2441
 
 
2442
 
\<trace element\><<<
2443
 
if( trace ){
2444
 
   logWriter.print( "= xtpipes => " + instruction );
2445
 
   if( node.hasAttributes() ){
2446
 
      NamedNodeMap attributes = node.getAttributes();
2447
 
      for(int i=0; i < attributes.getLength(); i++ ){
2448
 
         Node attr = attributes.item(i);
2449
 
         logWriter.print( " "   + attr.getNodeName() 
2450
 
                         + "=\"" + attr.getNodeValue() + "\"" );
2451
 
   } } 
2452
 
   logWriter.println(); Xtpipes.logWriter.flush();
2453
 
}
2454
 
>>>
2455
 
 
2456
 
\<trace if true\><<<
2457
 
if( trace ){
2458
 
   logWriter.print( "--> true" );
2459
 
}
2460
 
>>>
2461
 
 
2462
 
\<trace if false\><<<
2463
 
if( trace ){
2464
 
   logWriter.print( "--> true" );
2465
 
}
2466
 
>>>
2467
 
 
2468
 
 
2469
 
\<trace open script\><<<
2470
 
if( trace ){
2471
 
   logWriter.println( "(" + scriptFile + ")" );
2472
 
}
2473
 
>>>
 
3712
 
 
3713
The follower listeners catch errors but their messages are not
 
3714
delivered through the call to the new exceptions (why?).  The field
 
3715
errMssg is used so that error 16 will produce the same error messages.
 
3716
 
 
3717
\begin{description}
 
3718
\item[Catches errors in the XSLT file]
 
3719
 
 
3720
 
 
3721
 
 
3722
\<transformer factory XSLT error listener\><<<
 
3723
new ErrorListener() {
 
3724
   public void warning(TransformerException e) throws TransformerException {
 
3725
     showSpecifics(e);
 
3726
   }
 
3727
   public void error(TransformerException e) throws TransformerException {
 
3728
     showSpecifics(e);
 
3729
   }
 
3730
   public void fatalError(TransformerException e) throws TransformerException {
 
3731
     showSpecifics(e);
 
3732
   }          
 
3733
   void showSpecifics(TransformerException e)
 
3734
                                               throws  TransformerException{
 
3735
     String err = e.getMessage() ;
 
3736
     String loc = e.getLocationAsString();
 
3737
     if( loc != null ){ err = loc + ": " + err; }
 
3738
     err = "XSL stylesheet problem: " + err;
 
3739
     if( errMssg == null ){ errMssg = err; }
 
3740
     throw new TransformerException(err);
 
3741
}  }
 
3742
>>>
 
3743
 
 
3744
 
 
3745
\item [Catches errors in the XML file]
 
3746
 
 
3747
\<transformer XML error listener\><<<
 
3748
new ErrorListener() {
 
3749
   public void warning(TransformerException e) throws TransformerException {
 
3750
     showSpecifics(e);
 
3751
   }
 
3752
   public void error(TransformerException e) throws TransformerException {
 
3753
     showSpecifics(e);
 
3754
   }
 
3755
   public void fatalError(TransformerException e) throws TransformerException {
 
3756
     showSpecifics(e);
 
3757
   }          
 
3758
   void showSpecifics(TransformerException e)
 
3759
                                               throws  TransformerException{
 
3760
     String err = e.getMessage() ;
 
3761
     String loc = e.getLocationAsString();
 
3762
     if( loc != null ){ err = loc + ": " + err; }
 
3763
     if( errMssg == null ){ errMssg = err; }
 
3764
     err = "XML document prblem: " + err;
 
3765
     throw new TransformerException(err);
 
3766
}  }
 
3767
>>>
 
3768
 
 
3769
 
 
3770
\<identity transformer XML error listener\><<<
 
3771
new ErrorListener() {
 
3772
   public void warning(TransformerException e) throws TransformerException {
 
3773
     showSpecifics(e);
 
3774
   }
 
3775
   public void error(TransformerException e) throws TransformerException {
 
3776
     showSpecifics(e);
 
3777
   }
 
3778
   public void fatalError(TransformerException e) throws TransformerException {
 
3779
     showSpecifics(e);
 
3780
   }          
 
3781
   void showSpecifics(TransformerException e)
 
3782
                                               throws  TransformerException{
 
3783
     String err = e.getMessage() ;
 
3784
     String loc = e.getLocationAsString();
 
3785
     if( loc != null ){ err = loc + ": " + err; }
 
3786
     throw new TransformerException(err);
 
3787
}  }
 
3788
>>>
 
3789
 
 
3790
 
 
3791
 
 
3792
\end{description}
 
3793
 
 
3794
 
 
3795
\<xtpipes fields\><<<
 
3796
public static String errMssg;
 
3797
>>>
 
3798
 
 
3799
%%%%%%%%%%%%%%%%%%
 
3800
\section{Serialize Dom}
 
3801
%%%%%%%%%%%%%%%%%%
 
3802
 
 
3803
 
 
3804
\<static String serialize( dom )\><<<
 
3805
static String serialize( Node root ){
 
3806
   if( root.getNodeType() == Node.TEXT_NODE) { 
 
3807
         return root.getNodeValue(); 
 
3808
   }   
 
3809
   if( root.getNodeType() == Node.ELEMENT_NODE) { 
 
3810
      String ser = "";
 
3811
      String tagName = root.getNodeName();
 
3812
      ser += "<" + tagName;
 
3813
      `<res += serialize attributes`>
 
3814
      ser += "\n>";
 
3815
      `<res += serialize children`>
 
3816
      ser += "</" + tagName + ">";
 
3817
      return ser;
 
3818
   }
 
3819
   if( root.getNodeType() == Node.DOCUMENT_NODE) { 
 
3820
      String ser = "";
 
3821
      `<res += serialize children`>
 
3822
      return ser;
 
3823
   }   
 
3824
   if( root == null ){ return "null"; }
 
3825
   return "";
 
3826
}
 
3827
>>>
 
3828
 
 
3829
\<res += serialize children\><<<
 
3830
NodeList children = root.getChildNodes(); 
 
3831
if(children.getLength() > 0) { 
 
3832
   for(int i = 0; i < children.getLength(); i++) { 
 
3833
      ser += serialize(children.item(i)); 
 
3834
}  } 
 
3835
>>>
 
3836
 
 
3837
\<res += serialize attributes\><<<
 
3838
NamedNodeMap attributes = root.getAttributes(); 
 
3839
for(int i = 0; i < attributes.getLength(); i++) { 
 
3840
   Attr attribute = (Attr) attributes.item(i); 
 
3841
   ser += "\n" + attribute.getName() + "=\"" 
 
3842
               + attribute.getValue() + "\" ";  
 
3843
}  
 
3844
>>>
 
3845
 
 
3846
 
 
3847
 
 
3848
 
 
3849
%%%%%%%%%%%%% 
 
3850
\subsection{Clean Xmlns} 
 
3851
%%%%%%%%%%%%% 
 
3852
 
 
3853
 
 
3854
\<static void cleanXmlns( dom )\><<< 
 
3855
static ArrayList<String> nsName, nsValue;
 
3856
static void cleanXmlns( Node root ){ 
 
3857
   if( root.getNodeType() == Node.ELEMENT_NODE) {  
 
3858
      int top = nsName.size();
 
3859
      `<clean xmlns attributes`> 
 
3860
      `<clean xmlns in children`> 
 
3861
       for(int i=nsName.size(); i>top; ){
 
3862
         i--;
 
3863
         nsName.remove(i);
 
3864
         nsValue.remove(i);
 
3865
       }
 
3866
   } else if( root.getNodeType() == Node.DOCUMENT_NODE) {  
 
3867
      nsName = new ArrayList<String>();
 
3868
      nsValue = new ArrayList<String>();
 
3869
      `<clean xmlns in children`> 
 
3870
      nsName = null;
 
3871
      nsValue = null;
 
3872
}  } 
 
3873
>>> 
 
3874
 
 
3875
 
 
3876
 
 
3877
\<clean xmlns in children\><<< 
 
3878
NodeList children = root.getChildNodes();  
 
3879
if(children.getLength() > 0) {  
 
3880
   for(int i = 0; i < children.getLength(); i++) {  
 
3881
      cleanXmlns(children.item(i));  
 
3882
}  }  
 
3883
>>> 
 
3884
 
 
3885
\<clean xmlns attributes\><<< 
 
3886
ArrayList<Attr> remove = new ArrayList<Attr>();
 
3887
NamedNodeMap attributes = root.getAttributes();  
 
3888
for(int i = 0; i < attributes.getLength(); i++) {  
 
3889
   Attr attribute = (Attr) attributes.item(i);  
 
3890
   String name = attribute.getName();           
 
3891
   if( name.startsWith("xmlns") ){     
 
3892
     if( (name.length() == 5) || (name.charAt(5) == ':') ){
 
3893
        String value = attribute.getValue();
 
3894
        `<bool := xmlns active?`>
 
3895
        if( bool ){ remove.add(attribute);
 
3896
        } else { nsName.add(name); nsValue.add(value); }
 
3897
}  } }   
 
3898
for(int i=remove.size(); i>0; ){
 
3899
   i--;
 
3900
  ((Element) root).removeAttributeNode( (Attr) remove.get(i) );
 
3901
}
 
3902
remove = null;
 
3903
>>> 
 
3904
 
 
3905
\<bool := xmlns active?\><<<
 
3906
boolean bool = false;
 
3907
for(int k=nsName.size(); k>0; ){ 
 
3908
  k--;
 
3909
  if( ((String) nsName.get(k)) . equals(name) ){
 
3910
     bool = ((String) nsValue.get(k)) . equals(value);
 
3911
     break;
 
3912
} }
 
3913
>>>
 
3914
 
 
3915
\<xtpipes imports\><<<
 
3916
import java.util.ArrayList;
 
3917
>>>
 
3918
 
2474
3919
 
2475
3920
 
2476
3921
%%%%%%%%%%%%%%%%%%
2482
3927
   \OutputCodE\<xtpipes-default.4xt\>
2483
3928
}
2484
3929
 
2485
 
\AddFile(/home/4/gurari/tex4ht.dir/texmf/tex4ht/bin){xtpipes-default.4xt}{xtpipes/lib}
 
3930
\expandafter\AddFile\BIN{xtpipes-default.4xt}{xtpipes\Slash lib}
2486
3931
 
2487
3932
 
2488
3933
 
2493
3938
>>>
2494
3939
 
2495
3940
 
 
3941
 
 
3942
 
 
3943
 
 
3944
 
 
3945
 
 
3946
 
 
3947
 
 
3948
 
 
3949
 
 
3950
 
 
3951
%%%%%%%%%%%%%%%%%%
 
3952
\part{Useful Pre Fabricated Modules}
 
3953
%%%%%%%%%%%%%%%%%%
 
3954
 
 
3955
 
 
3956
 
 
3957
 
 
3958
%%%%%%%%%%%%%
 
3959
\section{ScriptsManager: A Content Handler}
 
3960
%%%%%%%%%%%%%
 
3961
 
 
3962
\label{ScriptsManager}
 
3963
 
 
3964
 
 
3965
%%%%%%%%%%%%%
 
3966
\subsection{Outline}
 
3967
%%%%%%%%%%%%%
 
3968
 
 
3969
 
 
3970
\AtEndDocument{
 
3971
   \OutputCodE\<ScriptsManager.java\>
 
3972
}
 
3973
\AddFile{ScriptsManager.java}{xtpipes\Slash util}
 
3974
 
 
3975
 
 
3976
\<ScriptsManager.java\><<<
 
3977
// `version
 
3978
package xtpipes.util;
 
3979
`<ScriptsManager imports`>
 
3980
 
 
3981
import org.xml.sax.helpers.DefaultHandler;
 
3982
import org.xml.sax.*;     
 
3983
import java.io.*;     
 
3984
import java.lang.reflect.*;
 
3985
import java.util.HashMap;
 
3986
import java.util.Stack; 
 
3987
 
 
3988
public class ScriptsManager extends DefaultHandler {
 
3989
     `<ScriptsManager fields`>
 
3990
     PrintWriter out = null, log = null;
 
3991
     HashMap<String,Object> scripts = null;
 
3992
     Method method = null;
 
3993
     boolean savemode=false;
 
3994
     String code="", match = null;
 
3995
     Stack<Object[]> stack = new Stack<Object[]>();
 
3996
   public ScriptsManager( PrintWriter out, 
 
3997
                          HashMap<String,Object> scripts, Method method,
 
3998
                          PrintWriter log, boolean trace ){
 
3999
     this.out = out;
 
4000
     this.log = (log==null)? new PrintWriter( System.err ) : log;
 
4001
     this.scripts = scripts;
 
4002
     this.method = method;
 
4003
   }
 
4004
   public void characters(char[] ch, int start, int length){
 
4005
     add( XtpipesUni.toUni(ch, start, length, "<>&") );
 
4006
   }
 
4007
   `<ScriptsManager: void startElement(ns, sName, qName, atts)`>
 
4008
   `<ScriptsManager: void endElement(ns, sName, qName)`>
 
4009
   void add(String s){
 
4010
      if( savemode ){ code+=s; }
 
4011
      else { out.print(s); }
 
4012
}  }
 
4013
>>>
 
4014
 
 
4015
 
 
4016
%%%%%%%%%%%%%
 
4017
\subsection{Start Elements}
 
4018
%%%%%%%%%%%%%
 
4019
 
 
4020
 
 
4021
 
 
4022
 
 
4023
\<ScriptsManager: void startElement(ns, sName, qName, atts)\><<<
 
4024
public void startElement(String ns, String sName,
 
4025
                        String qName, Attributes atts) {
 
4026
   `<save status of xmlns above element`>
 
4027
   `<flag := start new save?`>
 
4028
   inBody = true;
 
4029
   String s =  "<" + qName + "\n";
 
4030
   for(int i=0; i<atts.getLength(); i++ ){
 
4031
      String name = atts.getQName(i),
 
4032
             value = atts.getValue(i);
 
4033
      `<record xmlns`>
 
4034
      s += " " + name + "=\"" + 
 
4035
         XtpipesUni.toUni(value, "<>&\"") + "\"";
 
4036
   } 
 
4037
   if( flag ){ `<add missing xmlns attributes`> }
 
4038
   s += ">" ;
 
4039
   `<set start element`>
 
4040
}
 
4041
>>>
 
4042
 
 
4043
 
 
4044
\<ScriptsManager fields\><<<
 
4045
boolean inBody = false;
 
4046
>>>
 
4047
 
 
4048
 
 
4049
\<flag := start new save?\><<<
 
4050
String key = (atts==null)?
 
4051
               null 
 
4052
             : (qName + "::" + atts.getValue("class"));
 
4053
boolean flag = (key != null) && scripts.containsKey(key);
 
4054
 
 
4055
if( !flag ){
 
4056
   key = qName;
 
4057
   flag = scripts.containsKey(key);
 
4058
}
 
4059
>>>
 
4060
 
 
4061
\<set start element\><<<
 
4062
if( flag ){ 
 
4063
   Object [] state = { new Boolean(savemode), code, match }; 
 
4064
   stack.push( state );
 
4065
   savemode=true; code=""; match= key;
 
4066
} else {
 
4067
   Object [] state = { new Boolean(savemode), null, null }; 
 
4068
   stack.push( state );
 
4069
}
 
4070
add( s );
 
4071
>>>
 
4072
 
 
4073
The parsing of an XML string is similar to that of done by a
 
4074
left-to-right bottom up parser of a programming language.
 
4075
Specifically, the token are read and send on to the output stream,
 
4076
until an element whose name appears in the hash table of scripts is
 
4077
encountered.  When such an element is encountered, its body is
 
4078
assembled and the corresponding script is applied on the body.  The
 
4079
processing might be recursive, in the sense that enclosed elements
 
4080
might also have scripts to process them.
 
4081
 
 
4082
The above applies also to an element name concatenated with its class
 
4083
attribute value, with the substring `::' as a separator.
 
4084
 
 
4085
%%%%%%%%%%%%%
 
4086
\subsection{End Elements}
 
4087
%%%%%%%%%%%%%
 
4088
 
 
4089
 
 
4090
 
 
4091
\<ScriptsManager: void endElement(ns, sName, qName)\><<<
 
4092
public void endElement(String ns, String sName, String qName){
 
4093
   String s = "</" + qName + ">";
 
4094
   add( s );
 
4095
   Object [] state = (Object []) stack.pop();     
 
4096
   if( (String) state[1] != null ){ 
 
4097
     `<invoke script`>
 
4098
     `<set end element`>
 
4099
     `<recall status of xmlns above element`>
 
4100
     `<remove xmlns attributes supported from above`>
 
4101
     add( s );
 
4102
   } else { `<recall status of xmlns above element`> }
 
4103
}
 
4104
>>>
 
4105
 
 
4106
 
 
4107
 
 
4108
 
 
4109
 
 
4110
 
 
4111
 
 
4112
\<invoke script\><<<
 
4113
Object parmValues[] = new Object[2]; 
 
4114
parmValues[0] = scripts.get( match );
 
4115
parmValues[1] = code; 
 
4116
try { 
 
4117
  s = (String) method.invoke( null, parmValues ); 
 
4118
} catch(java.lang.reflect.InvocationTargetException e){
 
4119
   log.println("--- ScriptsManager Error 1 --- " + e.getCause() );
 
4120
   log.flush();
 
4121
} catch (Exception e){
 
4122
   log.println("--- ScriptsManager Error 2 --- " + e );
 
4123
   log.flush();
 
4124
}
 
4125
>>>
 
4126
 
 
4127
 
 
4128
Can't invoke exception above.
 
4129
 
 
4130
\<set end element\><<<  
 
4131
savemode = ((Boolean) state[0]).booleanValue();
 
4132
code = (String) state[1]; 
 
4133
match = (String) state[2];
 
4134
>>>
 
4135
 
 
4136
 
 
4137
 
 
4138
 
 
4139
%%%%%%%%%%%%%
 
4140
\subsection{Name Spaces}
 
4141
%%%%%%%%%%%%%
 
4142
 
 
4143
\<record xmlns\><<<
 
4144
if( name.startsWith("xmlns") ){     
 
4145
  if( (name.length() == 5) || (name.charAt(5) == ':') ){
 
4146
     `<bool := xmlns active?`>
 
4147
     if( !bool ){ 
 
4148
        nsName.add(name); nsValue.add(value); 
 
4149
} }  }
 
4150
>>>
 
4151
 
 
4152
 
 
4153
 
 
4154
 
 
4155
\<save status of xmlns above element\><<<
 
4156
int top = nsName.size();
 
4157
nsStack.push( new Integer(top) );
 
4158
>>>
 
4159
 
 
4160
\<recall status of xmlns above element\><<<
 
4161
int top = ((Integer) nsStack.pop()) . intValue();
 
4162
for(int i=nsName.size(); i>top; ){
 
4163
  i--;
 
4164
  nsName.remove(i);
 
4165
  nsValue.remove(i);
 
4166
}
 
4167
>>>
 
4168
 
 
4169
 
 
4170
 
 
4171
 
 
4172
\<add missing xmlns attributes\><<<
 
4173
HashSet<String> registry = new HashSet<String>();
 
4174
for(int i=nsName.size(); i>top; ){
 
4175
  i--;
 
4176
  registry.add( (String) nsName.get(i) );
 
4177
}
 
4178
for(int i=top; i>0; ){
 
4179
  i--;
 
4180
  String nm = (String) nsName.get(i);
 
4181
  if( ! registry.contains(nm) ){
 
4182
     registry.add( nm );
 
4183
     s += " " + nm + "=\"" + 
 
4184
         XtpipesUni.toUni( (String) nsValue.get(i), "<>&\"") + "\"";
 
4185
} }
 
4186
>>>
 
4187
 
 
4188
 
 
4189
 
 
4190
 
 
4191
\<ScriptsManager fields\><<<
 
4192
ArrayList<String> nsName = new ArrayList<String>(), 
 
4193
                         nsValue = new ArrayList<String>();
 
4194
Stack<Integer> nsStack = new Stack<Integer>();
 
4195
>>>
 
4196
 
 
4197
\<ScriptsManager imports\><<<
 
4198
import java.util.ArrayList;
 
4199
import java.util.HashSet;
 
4200
import xtpipes.XtpipesUni;
 
4201
>>>
 
4202
 
 
4203
\<remove xmlns attributes supported from above\><<<
 
4204
int m = s.indexOf('>');
 
4205
char [] attrs = s.substring(0,m).toCharArray();
 
4206
int result = qName.length()+1, 
 
4207
    mark = result,
 
4208
    from=-1,
 
4209
    control = `<xmlns name`>;
 
4210
char delimiter = ' ';
 
4211
String name="";
 
4212
 
 
4213
for(int i=result; i<m; i++ ){
 
4214
  attrs[result++] = attrs[i]; 
 
4215
  switch( control ){
 
4216
    case  `<xmlns name`>: { `<insert attribute name`>      break; }
 
4217
    case `<xmlns quote`>: { `<insert attribute quote`>     break; }
 
4218
    case `<xmlns value`>: { `<insert attribute value`> break; }
 
4219
} }
 
4220
s =  (new String(attrs,0,result)) + s.substring(m);
 
4221
>>>
 
4222
 
 
4223
 
 
4224
 
 
4225
\<insert attribute name\><<<
 
4226
if( attrs[i] == '=' ){
 
4227
   name = (new String(attrs,mark,result-mark-1)).trim();
 
4228
   control = `<xmlns quote`>;   
 
4229
 
4230
>>>
 
4231
 
 
4232
\<insert attribute quote\><<<
 
4233
if( (attrs[i] == '"') || (attrs[i] == '\'') ){
 
4234
   delimiter = attrs[i];
 
4235
   control = `<xmlns value`>;
 
4236
   from = result;
 
4237
}
 
4238
>>>
 
4239
 
 
4240
\<insert attribute value\><<<
 
4241
if( attrs[i] == delimiter ){
 
4242
   if( name.startsWith("xmlns") 
 
4243
       && ((name.length() == 5) || (name.charAt(5) == ':')) ){
 
4244
      String value = (new String(attrs,from,result-from-1)).trim();
 
4245
      `<bool := xmlns active?`>
 
4246
      if( bool ){ result = mark; }
 
4247
   }
 
4248
   mark = result;
 
4249
   control = `<xmlns name`>;
 
4250
 
4251
>>>
 
4252
 
 
4253
 
 
4254
 
 
4255
\OP{xmlns name}
 
4256
\OP{xmlns quote}
 
4257
\OP{xmlns value}
 
4258
 
 
4259
 
 
4260
%%%%%%%%%%%%%%%%%%
 
4261
\section{ScriptsManagerLH: A Lexical Handler}
 
4262
%%%%%%%%%%%%%%%%%%
 
4263
 
 
4264
\label{ScriptsManagerLH}
 
4265
 
 
4266
 
 
4267
The lexical handler sends its strings to the content hadler.
 
4268
 
 
4269
 
 
4270
 
 
4271
\AtEndDocument{
 
4272
   \OutputCodE\<ScriptsManagerLH.java\>
 
4273
}
 
4274
 
 
4275
\AddFile{ScriptsManagerLH.java}{xtpipes\Slash util}
 
4276
 
 
4277
 
 
4278
 
 
4279
\<ScriptsManagerLH.java\><<<
 
4280
// `version
 
4281
package xtpipes.util;
 
4282
import org.xml.sax.ext.LexicalHandler;
 
4283
// import org.xml.sax.ContentHandler;     
 
4284
import java.io.PrintWriter;
 
4285
public class ScriptsManagerLH implements LexicalHandler {
 
4286
       ScriptsManager contentHandler;
 
4287
       PrintWriter log;
 
4288
   public ScriptsManagerLH( ScriptsManager contentHandler,
 
4289
                          PrintWriter log, boolean trace ){
 
4290
     this.contentHandler = contentHandler;
 
4291
     this.log = (log==null)? new PrintWriter( System.err ) : log;
 
4292
   }
 
4293
   public void comment(char[] ch, int start, int length){
 
4294
     if( contentHandler.inBody ){
 
4295
        String s = new String(ch, start, length);
 
4296
        contentHandler.add(  "<!--" + s + "\n-->");
 
4297
   } }
 
4298
   public void startEntity(String x){}
 
4299
   public void endEntity(String x){}
 
4300
   public void startCDATA(){}
 
4301
   public void endCDATA(){}
 
4302
   public void startDTD(String x, String y, String z){}
 
4303
   public void endDTD(){} 
 
4304
}
 
4305
>>>
 
4306
 
 
4307
\begin{itemize}
 
4308
\item
 
4309
The line breaks in the comments are to avoid sequences of comments 
 
4310
loosing their intermediate line breaks and as a result causing 
 
4311
overflow of buffers.
 
4312
 
 
4313
\item The comments in the preamble are included through the 
 
4314
preamble pattribute of xtpipes.
 
4315
\end{itemize}
 
4316
 
 
4317
 
 
4318
 
 
4319
 
 
4320
 
 
4321
 
 
4322
 
 
4323
 
 
4324
 
 
4325
 
 
4326
 
2496
4327
%%%%%%%%%%%%%%%%%%%%%%%
2497
4328
\begin{thebibliography}{10}
2498
4329
\bibitem{ref}
2504
4335
 
2505
4336
 
2506
4337
 
 
4338
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4339
 
 
4340
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4341
\ifOption{win}
 
4342
 
4343
     \AtEndDocument{
 
4344
        \OutputCodE\<dodoc.bat\>
 
4345
        \Needs{"dodoc"}
 
4346
     }  
 
4347
}
 
4348
{ \ifOption{doc}{
 
4349
  \AtEndDocument{\Needs{"
 
4350
     mkdir doc.dir
 
4351
     ;
 
4352
     cd doc.dir
 
4353
     ;
 
4354
     java 
 
4355
        -classpath 
 
4356
        ..:../cgjsapi.jar:../../../jldir.dir:../../../jldir.dir/jldoc.jar:../../../ml2xml.dir/ml2xml.dir/bin/ml2xml.jar
 
4357
        jldoc.Jldoc 
 
4358
        -title "Xtpipes APIs"  
 
4359
        ../work.dir
 
4360
     ;
 
4361
     cd ..
 
4362
     ;
 
4363
     /usr/bin/rm -r doc.dir
 
4364
  "}}}{}
 
4365
}
 
4366
 
 
4367
 
 
4368
 
 
4369
 
 
4370
\<dodoc.bat\><<<
 
4371
cd work.dir 
 
4372
if NOT EXIST bin mkdir bin
 
4373
 javac -Xlint:unchecked  -d bin  xtpipes/*.java  
 
4374
 javac -Xlint:unchecked  -d bin  xtpipes/util/*.java
 
4375
 javac -Xlint:unchecked  -d bin  *.java 
 
4376
cd bin
 
4377
 jar cf xtpipes.jar *
 
4378
cd ..
 
4379
cd xtpipes
 
4380
if NOT EXIST bin mkdir bin
 
4381
 move ..\bin\xtpipes.jar bin\.
 
4382
cd ..
 
4383
cd ..
 
4384
>>>
 
4385
 
 
4386
\ifOption{win}{
 
4387
\immediate\write16{......... work.dir\string \xtpipes\string \lib\string \*}
 
4388
\immediate\write16{......... work.dir\string \xtpipes\string \bin\string \xtpipes.jar}
 
4389
}{}
 
4390
 
 
4391
 
 
4392
\ifOption{doc}{\let\DOC\def}{}
 
4393
 
 
4394
 
 
4395
 
 
4396
\ifx\DOC\def 
 
4397
%%%%%%%%%%%%%%%%%%%%%%%
 
4398
\<dodoc.bat\><<<
 
4399
if NOT EXIST doc.dir mkdir doc.dir
 
4400
cd doc.dir
 
4401
java -classpath ../../jldoc.dir;../../jldoc.dir/jldoc.jar;../../ml2xml.dir/ml2xml.dir/bin/ml2xml.jar jldoc.Jldoc -title "Xtpipes APIs"  ../work.dir/xtpipes
 
4402
cd ..
 
4403
rmdir /s /q doc.dir
 
4404
>>>
 
4405
%%%%%%%%%%%%%%%
 
4406
 
 
4407
\fi
 
4408
\
 
4409
 
 
4410
 
 
4411
 
 
4412
 
 
4413
../../..;..;../../jldoc;../../xtpipes/cgjsapi.jar;../../xtpipes/xtpipes.jar;../../jldoc/jldoc.jar;../../ml2xml.dir/ml2xml.dir/bin/ml2xml.jar
 
4414
 
 
4415
\ifOption{win} {}{
 
4416
\AtEndDocument{\Needs{% 
 
4417
    "cd /home/4/gurari/xtpipes.dir 
 
4418
     ;   
 
4419
     jar cf tex4ht.jar * 
 
4420
     ; 
 
4421
     mv tex4ht.jar /home/4/gurari/tex4ht.dir/texmf/tex4ht/bin/.  
 
4422
     ; 
 
4423
     cp /home/4/gurari/xtpipes.dir/xtpipes/lib/*  
 
4424
        /home/4/gurari/tex4ht.dir/texmf/tex4ht/xtpipes/. 
 
4425
"}} 
 
4426
 
4427
 
 
4428
 
 
4429
 
2507
4430
\end{document}
2508
4431