Initial commit
[profile/ivi/openjade.git] / style / StyleEngine.cxx
1 // Copyright (c) 1996 James Clark
2 // See the file copying.txt for copying permission.
3
4 #include "stylelib.h"
5 #include "StyleEngine.h"
6 #include "Interpreter.h"
7 #include "InterpreterMessages.h"
8 #include "SchemeParser.h"
9 #include "FOTBuilder.h"
10 #include "DssslSpecEventHandler.h"
11 #include "ArcEngine.h"
12 #include "ProcessContext.h"
13 #include "macros.h"
14 #include "InternalInputSource.h"
15
16 #ifdef DSSSL_NAMESPACE
17 namespace DSSSL_NAMESPACE {
18 #endif
19
20 StyleEngine::StyleEngine(Messenger &mgr,
21                          GroveManager &groveManager,
22                          int unitsPerInch,
23                          bool debugMode,
24                          bool dsssl2,
25                          bool strictMode,
26                          const FOTBuilder::Extension *extensionTable)
27 : interpreter_(new Interpreter(&groveManager, &mgr, unitsPerInch, 
28                                debugMode, dsssl2, strictMode, extensionTable))
29 {
30 }
31
32 void StyleEngine::parseSpec(SgmlParser &specParser,
33                             const CharsetInfo &charset,
34                             const StringC &id,
35                             Messenger &mgr)
36 {
37   DssslSpecEventHandler specHandler(mgr);
38   Vector<DssslSpecEventHandler::Part *> parts;
39   specHandler.load(specParser, charset, id, parts);
40   for (int phase = 0; phase < 2; phase++) {
41     for (size_t i = 0; i < parts.size(); i++) {
42       DssslSpecEventHandler::Part::DIter diter(parts[i]->doc()->diter());
43       bool local = 0;
44       do {
45         if (local) 
46           diter = parts[i]->diter();
47         local = !local;
48         for (; !diter.done(); diter.next()) {
49           if ((diter.cur()->type() == DssslSpecEventHandler::DeclarationElement::charRepertoire ||
50                diter.cur()->type() == DssslSpecEventHandler::DeclarationElement::standardChars)
51               ? phase == 0
52               : phase == 1) {
53             Owner<InputSource> in;
54             diter.cur()->makeInputSource(specHandler, in);
55             SchemeParser scm(*interpreter_, in);
56             switch (diter.cur()->type()) {
57             case DssslSpecEventHandler::DeclarationElement::charRepertoire:
58               interpreter_->setCharRepertoire(diter.cur()->name());
59               break;
60             case DssslSpecEventHandler::DeclarationElement::standardChars:
61               scm.parseStandardChars(); 
62               break;
63             case DssslSpecEventHandler::DeclarationElement::mapSdataEntity:
64               scm.parseMapSdataEntity(diter.cur()->name(), diter.cur()->text());
65               break;
66             case DssslSpecEventHandler::DeclarationElement::addNameChars:
67               scm.parseNameChars();
68               break;
69             case DssslSpecEventHandler::DeclarationElement::addSeparatorChars:
70               scm.parseSeparatorChars();
71               break;
72             default:
73               interpreter_->message(
74                      InterpreterMessages::unsupportedDeclaration);
75              break;
76  
77             }
78           }
79         }
80       } while (local);
81       interpreter_->dEndPart();
82     }
83   }
84
85   if (cmdline.size() > 0) {  
86     Owner<InputSource> in(new InternalInputSource(cmdline,
87                           InputSourceOrigin::make()));
88     SchemeParser scm(*interpreter_, in);
89     scm.parse();
90     interpreter_->endPart();
91   }
92  
93   for (size_t i = 0; i < parts.size(); i++) {
94     for (DssslSpecEventHandler::Part::Iter iter(parts[i]->iter());
95          !iter.done();
96          iter.next()) {
97       Owner<InputSource> in;
98       iter.cur()->makeInputSource(specHandler, in);
99       if (in) {
100         SchemeParser scm(*interpreter_, in);
101         scm.parse();
102       }
103     }
104     interpreter_->endPart();
105   }
106   interpreter_->compile();
107 }
108
109 void StyleEngine::defineVariable(const StringC &str)
110 {
111   // Dk: Interpret "name=value" as a string variable Setting.
112   if (str[0] == '(') {
113     cmdline += str;
114   } 
115   else {
116     int i;
117     for (i = 0; (i < str.size()) && (str[i] != '='); i++)
118       ;
119
120     // Dk: Not name=value?
121     if (!i || (i >= (str.size()))) {  
122       cmdline += interpreter_->makeStringC("(define ");
123       cmdline += str;
124       cmdline += interpreter_->makeStringC(" #t)");
125     }
126     else {  
127       // Dk: name=value.
128       cmdline += interpreter_->makeStringC("(define ");
129       cmdline += StringC(str.begin(), i);
130       cmdline += interpreter_->makeStringC(" \"");
131       if (str.size() - (i + 1) > 0);
132         cmdline += StringC(str.begin() + i + 1, str.size() - (i + 1));
133       cmdline += interpreter_->makeStringC("\")");
134     }
135   }
136 }
137
138 StyleEngine::~StyleEngine()
139 {
140   delete interpreter_;
141 }
142
143 void StyleEngine::process(const NodePtr &node, FOTBuilder &fotb)
144 {
145   ProcessContext context(*interpreter_, fotb);
146   context.process(node);
147 }
148
149 #ifdef DSSSL_NAMESPACE
150 }
151 #endif